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.

user1930254
  • 1,251
  • 5
  • 17
  • 32
  • 1
    You might wanna take a look at: [RandomAccessFile](http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html) for reading and writing bytes – Matias Cicero Dec 19 '14 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. – Christophe Dec 19 '14 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](https://code.google.com/p/protobuf/). – πάντα ῥεῖ Dec 19 '14 at 18:01

2 Answers2

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++)

Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • @user1930254 it's super fast in C too if you use memory mapped files. – Peter Lawrey Dec 19 '14 at 18:35
  • @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? – Chief A Apr 25 '19 at 05:48
  • @ChiefA I am not familiar with C++ any more. – Peter Lawrey Apr 26 '19 at 14:03
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.
Christophe
  • 68,716
  • 7
  • 72
  • 138