4

I have a 500MB binary file. with a bunch of float entries. It was written by a C++ program. I would load it in C++ like this.

void load(char f_name[], int size, float data[])
{
    std::fstream f_bin(f_name, std::ios::in|std::ios::binary);

    f_bin.seekg(std::ios::beg);
    f_bin.read((char*)data, size*sizeof(float));
    f_bin.close();
}

float *data;
int size = 123456789;
data = new float[size];
load("myFile.bin", size, data);

And i can access the float values: data[x]; In c++ it works preatty fast. Is there something simular in java?

Edit After reading a bit around i have this so far:

        RandomAccessFile f = new RandomAccessFile("C://path//myFile.bin", "r");
        byte[] bytes = new byte[(int)f.length()];
        f.read(bytes);

        float fl = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat();     


        System.out.println(fl);

Which prints the first float entry. Now i should loop float by float and put it in an array like float[] data.

3
  • 1
    You might wanna take a look at: RandomAccessFile for reading and writing bytes Commented Dec 19, 2014 at 17:41
  • 1
    I think it's not a duplicate of "File to byte[] in java": this question is about reading C++ generated data AND ESPECIALLY FLOATS in a java programme, whereas the other question is only about reading a file as a byte array. Commented Dec 19, 2014 at 17:55
  • @user1930254 Do you have control over the c++ implementation? It might be a better choice, to store these float values in text format, or have some language interop capable serialization framework like e.g. google-protobuf. Commented Dec 19, 2014 at 18:01

2 Answers 2

3

You can do this in Java.

try(FileChannel fc = new RandomAccessFile("myFile.bin", "rw").getChannel()) {
    FloatBuffer fb = fc.map(MapMode.READ_WRITE, 0, fc.size())
                       .order(ByteOrder.nativeOrder()).asFloatBuffer();
    // use fb 
}

This is quite a bit faster as it memory maps the file and avoids a memory copy (you can do the same in C++)

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

3 Comments

@user1930254 it's super fast in C too if you use memory mapped files.
@PeterLawrey, I have a similar situation where I have written objects of a user-defined class into a file in binary mode from c++ and wants to read it from java. how should I change the above code to achieve that? would you kindly include the answer to this in your answer?
@ChiefA I am not familiar with C++ any more.
1

The Java standard is very precise about how floating points are to be represented:

Java virtual machine specification 2.3.2: The floating-point types are float and double, which are conceptually associated with the 32-bit single-precision and 64-bit double-precision format IEEE 754 values and operations as specified in IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-1985, New York).

But the C++ standard doesn't give many guarantees regarding this:

C++11 standard 3.9.1/8: There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. (...) The value representation of floating-point types is implementation-defined.

With <limits> you can in a portable way know a little bit more about your floats: std::numeric_limits<float>::is_iec559 will for example tell you if the IEC-559 / IEEE-754 standard (aka the same as java) is used:

  • If it is, you could then read the float, using binary data as it is. (Edit following PoweredByRice comment; in fact you still have to address potential endianness issues, because IEEE-754 leaves this point open. For more info on how to force a specific ordering on the C++ side, look here. On the java side you can force a byte ordering or use the default one).
  • If not, you'll have to read the bytes and write floating point format conversion routines, which usually proves to be challenging.

3 Comments

This answer while correctly mentions the importance of size, does not mention the other half of the picture that is endianness.
@PoweredByRice indeed, IEEE 754 does not specify endianness, so that there is a risk of incompatibility between different architectures.
@PoweredByRice post edited accordingly. Thanks for the hint !

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.