I have a data file that is made up of various fields in little-endian order. I know what the offset and length are for each of the various fields. Is there an existing Java class that will convert by offset and length to an integer? For example: 17 00 00 00 53 43 43 41 11 00 00 00 AA 35 00 00. Bytes 1 thru 4 (17 00 00 00) is 0x00000017.
Guava provides the LittleEndianDataInputStream
class which can be used to retrieve values in little endian order.
You can do that with a java.nio.IntBuffer
or java.nio.ByteBuffer
, in association with a java.nio.channels.FileChannel
to read the data.
You should try to read it as it is. Get block of 4 bytes and treat them as integers. I'm sure JVM already treats numbers little endian (as far as I know, all Intel/amd are so).
If your file is a file of raw bytes you can use ByteBuffer
to read the file in little endian mode, and then use asIntBuffer()
to read out the int
s through an IntBuffer
. If you need to navigate the file, you can use srcChan.position(targetPosition);
to skip to your next "field".
try (RandomAccessFile srcFile = new RandomAccessFile("data/data.bin", "r");
FileChannel srcChan = srcFile.getChannel();)
{
// Careful with these casts if you have large files - channel size is a long
ByteBuffer ib = ByteBuffer.allocate((int)srcChan.size());
ib.order(ByteOrder.LITTLE_ENDIAN);
srcChan.read(ib);
IntBuffer fb = ((ByteBuffer)ib.rewind()).asIntBuffer();
while (fb.hasRemaining())
System.out.println(fb.get());
}
Output:
23 1094927187 17 13738
If however you have a text file with a series of space delimited hex strings (the file format is unclear from your question) you'll have to add a bit of trickery to read that in, but once it is in you can use ByteBuffer
in little-endian mode to read out the integers again.
The general process would be:
inputString.split(" ")
String
array into a byte[]
ByteBuffer.wrap
to wrap the resulting byte[]
and walk through the int
sIt probably (not compile time tested) looks something like the below (which doesn't use an IntBuffer
, just to show an alternative method):
String input = "17 00 00 00 53 43 43 41 11 00 00 00 AA 35 00 00";
String[] source = input.split(" ");
byte[] sourceBytes = new byte[source.length];
for (int i = 0; i < source.length; i++) {
sourceBytes[i] = (byte)Integer.parseInt(source[i], 16);
}
ByteBuffer bb = ByteBuffer.wrap(sourceBytes);
bb.order(ByteOrder.LITTLE_ENDIAN);
while (bb.hasRemaining())
System.out.println(bb.getInt());
The output is the same as for the first approach.
User contributions licensed under CC BY-SA 3.0