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
,因为你将不可避免地遇到padding和endian -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带来的所有麻烦都不值得单独解决这个问题,但您可能已经在使用它了。