4

例如在 CI 中具有结构:

typedef struct {
    int number;
    double x1;
    double y1;
    double x2;
    double y2;
    double x3;
    double y3;
} CTRstruct;`

然后我将它写入文件fwrite(&tr, 1, sizeof(tr), fp);(tr - 它的 CTRstruct var,fp - 文件指针);

然后我需要用Java阅读它!我真的不知道如何从文件中读取结构......我试图用 阅读它ObjectInputStream(),最后一个想法是用 阅读,RandomAccessFile()但我也不知道如何......(readLong(), readDouble()也不起作用,它可以正常工作但不读取正确的数据)。那么,知道如何用 Java 从二进制文件中读取 C 结构吗?


如果它很有趣,我的版本读取整数(但它很丑,我不知道该怎么做double):

公共类 MyDataInputStream 扩展 DataInputStream{

public MyDataInputStream(InputStream AIs) {
    super(AIs);
}

public int readInt1() throws IOException{
    int ch1 = in.read();
    int ch2 = in.read();
    int ch3 = in.read();
    int ch4 = in.read();
    if ((ch1 | ch2 | ch3 | ch4) < 0)
        throw new EOFException();
    return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
}

使用 double 我们可以以相同的方式处理(例如使用 int 或使用 long (8bytes),然后使用本机 func 转换为 double )。

4

6 回答 6

5

您不应该使用fwrite整个struct,因为您将不可避免地遇到填充字节序的问题。structC 端将按照它在内存中的全部方式转储,以及编译器为性能等而放入的所有差距。这就是“不可移植性之母”!

相反,您应该使用协议缓冲区、JSON 或其他可移植序列化方式来完成您的任务。

于 2012-04-15T14:38:41.530 回答
4

使用将数据序列化到磁盘的库。这将使将其读回 Java 变得容易得多。确保库使用有据可查的存储格式。

于 2012-04-15T14:42:29.173 回答
2

您必须找出在您执行程序的架构中使用了这些 C 类型(int、double)的大小和字节序(感谢 andrew cooke),并在 Java 中使用相同大小的类型。

于 2012-04-15T14:32:19.513 回答
1

DataInputStream是在 Java 中读取原始输入的典型方法——我认为你应该能够做到

int number = dataInputStream.readInt();
double x1 = dataInputStream.readDouble();
...
double y3 = dataInputStream.readDouble();

但我不能 100% 确定字节顺序和其他问题是否兼容。

于 2012-04-15T14:33:31.347 回答
1

好吧,万一您可以选择 JNI,您可以在 C 中读回它。使用swig,您可以轻松地公开您的结构,以及它从文件中读取的函数。当然,JNI 带来的所有麻烦都不值得单独解决这个问题,但您可能已经在使用它。

于 2012-04-15T14:53:03.160 回答
0

我使用http://javolution.org/(或https://github.com/javolution/javolution)。即使该项目看起来“死”了,我也没有发现任何比“结构”更简单有效的东西。

看看这里了解如何创建一个映射缓冲区的类: Struct Javadoc

于 2021-09-22T08:29:07.840 回答