Произвольный доступ к двоичным данным VB6 из Java

Я пытаюсь написать распределенное приложение на Java, однако программа, которую я пишу, заменяет эквивалент VB6. Используемые файлы данных - это живые файлы, содержащие двоичные данные, записанные с использованием методов put VB6, которые постоянно используются несколькими приложениями.

Я успешно извлек текст из файла, прочитав всю запись (160 байт) в массив байтов buf. Затем, используя следующую строку, извлеките текстовые поля

new String(Arrays.copyOfRange(buf, 15, 40), "ISO-8859-1");

Мне также нужно извлечь типы данных VB6 Boolean, Double, Integer, Long и Single. В конце концов, мне, вероятно, понадобится и datetime, но не на первом этапе. Чтобы делать удвоения, я знаю, что порядок байтов в VB6 является Little endian, а не big, поэтому у меня есть следующая функция

public static double toDouble(byte[] bytes) {
    return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getDouble();
}

Первые несколько полей данных представляют собой строки, затем 2 двойных, на данный момент вывод:

Barcode: 1            
Dept Code: 18
Description: MISC NON VAT             
Trade Price: 0.0
Retail Price: 0.009999999776482582

Как видите, первые 3 логичны и соответствуют содержимому файла данных. Торговая цена должна быть 0,0, так что это нормально, но розничная цена должна быть 0,01, что было бы правильно, если бы я округлил ее, но: A. Мне неудобно округлять цену и информацию о НДС, и B. Я не могу разумно записать какие-либо изменения обратно в файл, как будто я читаю с погрешностью или погрешностью, тогда я, вероятно, буду писать с такой же погрешностью. Я также пробовал вручную сдвиг битов, но для двойного Java жалуется, если я пытаюсь сдвинуть более 31 бита, что, конечно, мне нужно, чтобы сделать 56.

Любая помощь по этому поводу будет очень признательна


person feldoh    schedule 05.07.2012    source источник
comment
Я просто подумал, что должен добавить, я знаю, что с подобными вещами уже сталкивались на этом сайте раньше, и я прошу прощения за аналогичный вопрос, но мой прогресс до сих пор был связан с другими вопросами, и, как я уже упоминал в вопросе, что у меня есть done не совсем правильно, и я не понимаю, почему.   -  person feldoh    schedule 05.07.2012
comment
Лучшим решением было бы, если бы библиотека Java для такого рода вещей уже существовала, но я не могу ее найти.   -  person feldoh    schedule 05.07.2012
comment
Я хотел бы привести образец файла данных, но, поскольку он в основном нулевой и двоичный, он не совсем подходит для публикации. Если есть место, где я могу поделиться двоичными данными, пожалуйста, дайте мне знать   -  person feldoh    schedule 05.07.2012


Ответы (1)


Если бы я пытался это сделать, я бы написал VB6StreamReader, который инкапсулирует чтение примитивов VB6 и имеет дело с причудами в данных, которые возникают из-за того, как данные записываются через Put in VB6.

Что касается округления, большинство чисел с плавающей запятой представлены так, как вы описали. Вы обеспокоены тем, что VB6 нестандартно кодирует числа с плавающей запятой? Visual Basic использует IEEE 754.


Полезный калькулятор IEEE-754: http://babbage.cs.qc.cuny.edu/IEEE-754/

person tcarvin    schedule 05.07.2012
comment
Спасибо за ответ, я пытаюсь создать общий класс, который будет делать это для всех файлов, поэтому я сказал, что в конечном итоге мне понадобится datetime. Но вот что меня беспокоит, так это возможная потеря точности. Если VB6 представляет 0,01 как 0,009999999776482582 в глазах Java, тогда округление до нескольких DP, вероятно, нормально, но, допустим, я хочу увеличить это до 0,07. Мой инстинкт состоит в том, что он, вероятно, должен выглядеть примерно как 0,069999999776482582, иначе VB6 может счесть его 0,070000000334628528 или что-то такое, что, если я буду продолжать писать его туда и обратно, разница будет расти до проблем. - person feldoh; 05.07.2012
comment
Байты 0,0,0,64, -31,122, -124,63 дают 0,01 в VB6, но 0,009999999776482582, используя то, что у меня есть на Java, в чем разница и как я могу это учесть, более точно то, что я прошу - person feldoh; 05.07.2012
comment
Я поместил упомянутые вами байты (шестнадцатеричное 00,00,00,40, E1,7A, 84,3F) в файл и прочитал их в VB6 с помощью и вывел в MsgBox и получил 0,00999999977648258. - person tcarvin; 05.07.2012
comment
возможно, это то, как я получаю байты в первую очередь. В 6 я просто использую вход в пользовательский тип, я предполагал, что Java правильно считывает байты, я проверю это. - person feldoh; 05.07.2012
comment
Вы уверены, что значения в VB6 соответствуют вашим словам? Или это может быть просто отображаемое значение? - person jmoreno; 06.07.2012