在 Java 中读取C++二进制文件

reading C++ binary file in Java

本文关键字:C++ 二进制文件 读取 Java      更新时间:2023-10-16

我有一个 500MB 的二进制文件。 带有一堆浮点条目。它是由一个C++程序编写的。我会像这样C++加载它。

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

我可以访问浮点值:数据[x];在 c++ 中,它运行速度很快。Java中有什么模拟的东西吗?

编辑在阅读了一会儿之后,到目前为止我有这个:

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

打印第一个浮点条目。现在我应该按浮点数循环浮点数并将其放入像 float[] data 这样的数组中。

你可以在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 
}

这要快得多,因为它可以映射文件并避免内存副本(您可以在C++中执行相同的操作(

Java 标准非常精确地表示浮点:

Java 虚拟机规范 2.3.2:浮点类型为浮点型和双精度型,它们在概念上与 32 位单精度和 64 位双精度格式 IEEE 754 IEEE 二进制标准中指定的值和运算 浮点运算(ANSI/IEEE Std. 754-1985,纽约(。

但是C++标准对此并没有给出很多保证:

C++11 标准 3.9.1/8:有三种浮点类型:浮点型、双精度型和长型双精度型。双精度型提供至少与 浮点型,长双精度型提供至少与 双。 (...)浮点类型的值表示形式为 实现定义

有了<limits>,你可以以一种便携的方式更多地了解你的浮子:例如,std::numeric_limits<float>::is_iec559会告诉你是否使用了IEC-559/IEEE-754标准(又名与java相同(:

  • 如果是,则可以按原样使用二进制数据读取浮点数。 (编辑以下PoweredByRice评论;事实上,您仍然需要解决潜在的字节序问题,因为IEEE-754将这一点保留下来。 有关如何在C++端强制特定排序的更多信息,请查看此处。 在 java 端,您可以强制字节排序或使用默认的字节排序(。
  • 如果没有,则必须读取字节并编写浮点格式转换例程,这通常具有挑战性。