C struct写在文件中,用Java打开

例如在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阅读它! 我真的不知道如何从文件中读取struct …我试图用ObjectInputStream()读取它,最后的想法是用RandomAccessFile()读取但我也不知道如何…( readLong(), readDouble()也不起作用,它工作原理但不读取正确的数据)。 那么,任何想法如何用Java从二进制文件中读取C结构?


如果它很有意思,我的版本读取整数(但它很丑,我不知道如何处理double ):

public class 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)然后使用native func转换为double)。

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

你不应该使用整个struct fwrite ,因为你将不可避免地遇到paddingendian -ness的问题。 C方将按照它在内存中的方式转储整个struct ,包含编译器为性能等所有的空白。这就是“不可移植之母”!

相反,您应该使用协议缓冲区,JSON或其他一些便携式序列化来完成您的任务。

使用将数据序列化到磁盘的库 。 这将使它更容易阅读回Java。 确保库使用记录良好的存储格式。

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

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

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

好吧,万一JNI是你的选择,你可以在C中读回来。使用swig你可以很容易地暴露你的结构,以及它从文件中读取的function。 当然,JNI带来的所有麻烦都不值得单独解决这个问题,但您可能已经在使用它了。