例如在C中我有结构:
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)&amp;然后使用native func转换为double)。
答案 0 :(得分:5)
您不应该使用整个fwrite
中的struct
,因为您将不可避免地遇到 padding 和 endian -ness的问题。 C方将以整个struct
方式转储它在内存中的方式,以及编译器为性能等所有的差距。这就是“不可移植之母”!
相反,您应该使用协议缓冲区,JSON或其他一些便携式序列化来完成任务。
答案 1 :(得分:4)
使用library that serializes your data to disk。这将使阅读它变得更加容易。确保库使用记录良好的存储格式。
答案 2 :(得分:2)
您必须找出在执行程序的体系结构中使用这些C类型(int,double)和endianness(感谢andrew cooke)的大小,并在Java中使用相同大小的类型。
答案 3 :(得分:1)
DataInputStream
是在Java中读取原始输入的典型方法 - 我认为你应该能够做到
int number = dataInputStream.readInt();
double x1 = dataInputStream.readDouble();
...
double y3 = dataInputStream.readDouble();
但我并不是100%确定字节顺序和其他问题是兼容的。
答案 4 :(得分:1)
好吧,如果JNI是你的选择,你可以在C中阅读它。使用swig你可以轻松地公开你的结构,以及它从文件中读取的功能。当然,JNI带来的所有麻烦并不值得单独解决这个问题,但您可能已经在使用它了。