2014-01-12 4 views
4

У меня есть четко определенные двоичные данные, и я хочу написать Java API для него.
Формат файла подобенJava: разбор двоичных данных без знака

File Signature  char[4]    4 bytes 
File Source ID  unsigned short  2 bytes 
Header Size  unsigned long   4 bytes 
Max    double    8 bytes 

Я использую DataInputStream для анализа данных. char легко разобрать, без проблем. Но unsigned не может быть правильно разобран.
Я знаю, что Java не имеет беззнакового числа. Как его преобразовать? (Пожалуйста, примите пример unsigned long как пример).

EDIT

Вот код, который я Worte:

File file = new File("lidar.las"); 

DataInputStream in= new DataInputStream(new FileInputStream(file)); 

in.skipBytes(6); 

long read = (long) (in.readInt() & 0xFFFFFFFFL); 

System.out.println("read " + read); 


выход

чтения 3288596480

мое ожидаемое число - 1220 . Я не знаю кода, который написал эту двоичную запись, возможно, в c. Все, что я хочу, это написать версию Java для чтения данных.

решаемые
Я не уверен, что могу ответить на мой собственный вопрос. LOL
В любом случае, вот решения.

private static int getSignedInt(final int unsignedInt){ 

    ByteBuffer bb=ByteBuffer.allocate(1024*4); 

    bb.putInt(unsignedInt).flip(); 

    int result =bb.order(ByteOrder.LITTLE_ENDIAN).getInt(); 
    bb.clear(); 

    return result; 
} 
+0

Вам нужно сделать какую-то математику с ними? И вам нужно 8-байтовое целое без знака? Очевидный ответ заключается в том, чтобы прочитать их в целые числа со знаком, например, 4-байтовые беззнаковые длинные вставки на Java длинные. – Radiodef

+0

unsigned long не будет 4 байта в любой современной системе. Это в стороне, так как Java предлагает 8-байтовый подписанный длинный, который покрывает его. –

ответ

2

DataInputStream читает байты в Big Endian ориентации, но проверить это:

3288596480 = 0xC4040000

реверса байтов, вы получите 0x04C4 = 1220

Вы просто должны прочитать значения в Маленький Эндиан. Вопрос о знаке оказывается красной селедкой.

+0

Нужно ли мне перевернуть байты при чтении дважды? –

+0

Способ, которым я обычно занимаюсь удвоениями при разборе двоичных файлов, заключается в том, чтобы использовать существующий метод для чтения длинного (который да, вы отменили бы его), а затем вызовите Double.longBitsToDouble, чтобы преобразовать long в double. – Trejkaz

2

Просто прочитайте их short (2 байта - Java) и int (4 байта - Java) в вашем
кода Java. Вы не потеряете никакой информации. Если вам нужно вывести их позже,
выполните преобразование, чтобы вы не выводили подписанные числа.

Учитывая их имена: File Source ID и Header Size я сомневаюсь, что вы
будет делать любые арифметические операции над ними. Если да, будьте осторожны.

В качестве альтернативы, вы можете прочитать их обоих в long (8 байт в Java),
и не беспокоиться о арифметических операций, поскольку они не вызывают проблем.

В качестве альтернативы вы можете прочитать свои значения в виде массивов байтов в Java,
, а затем преобразовать их в соответствующие типы кода Java.
Это, вероятно, самое четкое и чистое решение.
Но для этого требуется больше кодирования.

+3

Преобразование подписанного int в положительное длинное в Java: long l = i & 0xFFFFFFFFL; –

+0

@ peter.petrov: извините, чтение его как долго не работает, оно дает мне отрицательный результат. Я смущен тем, что длинный 8 байтов, но размер заголовка 4 байта, Доза, что означает, что я добавил 4 дополнительных байта? –

+0

@Saddy_Grade Не знаете, что именно вы пытаетесь, но я предлагаю вам прочитать «Идентификатор исходного файла» и «Размер заголовка» - это байтовые массивы. Затем вы создаете из них длинные значения. См. Здесь: http://stackoverflow.com/questions/1026761/how-to-convert-a-byte-array-to-its-numeric-value-java –

Смежные вопросы