Reputation: 12207
I have a binary file which supposed to contain 32-bit floating point numbers. This file was written out from Objective-C code. My task is to read this file in Java.
I think i managed to do it in C++:
#include <fstream>
#include <iostream>
int main() {
float f;
std::ifstream fin("effect_0.cube", std::ios::binary);
while (fin.read(reinterpret_cast<char*>(&f), sizeof(float))) {
std::cout << f << "\n";
}
return 0;
}
This is how i interpret a float in Java
InputStream is = new FileInputStream("effect_0.cube");
DataInputStream dataInputStream = new DataInputStream(is);
float f = dataInputStream.readFloat();
But this returns totally wrong values.
I am running all this on OSX.
The file is here. It is very small. The values from C++ seem right, because they are in the correct range, but i got totally different values in Java. I also provide the hexdump -n 16 -s 256
:
0000100 00 00 00 00 91 90 90 3e 00 00 00 00 00 00 80 3f
0000110
Upvotes: 2
Views: 673
Reputation: 159086
The C code is writing in CPU endian order, which for Intel processors is little-endian.
DataInputStream
is reading in network byte order, which is big-endian.
The best way to read float
value in Java, where you can control the endian order, is to use a ByteBuffer
.
Sample code:
try (InputStream is = new FileInputStream("effect_0.cube")) {
ByteBuffer buf = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
for (int len; (len = is.read(buf.array())) == 4; ) {
buf.rewind();
float f = buf.getFloat();
System.out.println(f);
}
}
Upvotes: 4