4

I have a well defined binary data and I want to write Java API for it.
The file format is like

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

I am using DataInputStream for parsing the data. char is easy to parse, no problem. But unsigned cannot be parsed correctly.
I know Java has no unsigned number. How do I convert it? (Please take unsigned long as example).

EDIT

Here is the code I 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);


the output is

read 3288596480

my expected number is 1220 .I do not know the code that wrote this binary record, probably in c. All I want is writing a Java version to read data out.

Solved
I am not sure I can answer my own question. LOL
Anyway, Here is the solutions.

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;
}
2
  • Do you need to do some kind of math with them? And do you need an 8-byte unsigned integer? The sortof obvious answer is to read them in to signed integers, for example your 4-byte unsigned long fits in a Java long. Commented Jan 12, 2014 at 9:09
  • unsigned long is not going to be 4 bytes on any modern system. That aside, since Java offers a 8 byte signed long, that covers it. Commented Jan 12, 2014 at 9:38

2 Answers 2

2

DataInputStream reads bytes in Big Endian orientation, but check this out:

3288596480 = 0xC4040000

Reversing the bytes, you get 0x04C4 = 1220

You just have to read the values in Little Endian. The question about the sign turns out to be a red herring.

Sign up to request clarification or add additional context in comments.

1 Comment

The way I usually deal with doubles when parsing binary is to use the existing method to read a long (which yes, you would reverse) and then call Double.longBitsToDouble to convert the long to a double.
2

Just read them as short (2 bytes - Java) and int (4 bytes - Java) in your
Java code. You will not lose any information. If you need to output them later,
do a conversion so that you don't output signed numbers.

Given their names: File Source ID and Header Size I doubt you
will do any arithmetic operations on them. If you do, be careful.

Alternatively, you can read them both in long (8 bytes in Java),
and not worry about arithmetic operations as they will not cause issues.

Alternatively, you can read your values as byte arrays in Java,
and then transform them to the proper types in your Java code.
This is probably the most explicit and clean solution.
But it requires more coding.

8 Comments

To transform a signed int into an positive long in Java: long l = i & 0xFFFFFFFFL;
@peter.petrov: sorry, reading it as long does not work, it give me negative. I am confused that long take 8 bytes but the header size is 4 bytes, Dose that mean I added 4 extra bytes?
@Saddy_Grade Not sure what exactly you're trying but I suggest you read the 'File Source ID' and 'Header Size' are byte arrays. Then you construct long values from them. See here: stackoverflow.com/questions/1026761/…
@peter.petrov: I used readLong() & 0xFFFFFFFFL. it give me positive, but not correct number.
readLong() reads 8 bytes. Not just 4. If you want to read 4 bytes, then use readInt() and transform the result to a positive long using the bitmask.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.