从用Java编写的二进制文件中检索C中的double

时间:2016-05-08 02:37:16

标签: java c file byte

我正在将Java中的double值写入如下文件中,

byte[] bytes = new byte[8];
//Double d = new Double(4);
double d =1000;
ByteBuffer.wrap(bytes).putDouble(d);
File test = new File(FILE_PATH+"readme.bin");
test.createNewFile();
FileOutputStream ostream = new FileOutputStream(test);
ostream.write(bytes);
ostream.close();

我可以用Java代码读回来,但是当用C代码检索它时,我得到的值为0.000000。我的C代码如下,

FILE *file_ptr;
file_ptr = fopen(file_absolute,"rb");
if (!file_ptr)
{
    printf("Unable to open file!");
    return 1;
}
char bytes[8];
fread(&bytes, 8, 1, file_ptr);

double d = *((double*)bytes);
printf("%f",d);

我在这里遗漏了什么? C和Java代码都在同一系统上运行。

2 个答案:

答案 0 :(得分:0)

Java代码以与C期望相反的顺序输出字节。

所以你需要反转字节顺序。以下内容适用于标准的little-endian操作系统:

#include <stdio.h>

void main() {
  FILE *file_ptr;
  unsigned char bytes[sizeof(double)];
  union {
    double d;
    unsigned char bytes[sizeof(double)];
  } u;

  int c;

  file_ptr = fopen("float.bin","rb");
  fread(bytes,sizeof(double),1,file_ptr);

  for (c=0; c<sizeof(double); c++)
    u.bytes[c]=bytes[sizeof(double)-1-c];

  printf("%f\n", u.d);
}

只要目标系统对于我见过的任何标准系统和C编译器都是小端,这都可以。

如果要使代码更具可移植性,可以在编译时(使用宏,请参阅https://sourceforge.net/p/predef/wiki/Endianness/)或在运行时检测C代码的字节顺序。有一些不太常见的系统,特别是基于ARM和MIPS的系统,它们通常是大端的,并且这里不需要转换。无论底层系统如何,Java总是会产生大端输出,所以只有C代码需要是有条件的。

对于非常便携的版本,您可以使用宏检测字节顺序,或者在运行时,两个选项都在给定的链接中进行解释。如果您只是想在Windows上运行此代码,或者PC运行Linux,并且不关心可移植性,那么您可以使用上面的代码。

答案 1 :(得分:-1)

byte[] bytes = new byte[8];
//Double d = new Double(4);
double d =1000;
ByteBuffer.wrap(bytes).putDouble(d);
File test = new File(FILE_PATH+"readme.bin");
test.createNewFile();
FileOutputStream ostream = new FileOutputStream(test);
ostream.write(bytes);
ostream.close();

你不需要这一切。您可以在不到一半的代码中执行相同的操作:

DataOutputStream dos = new DataOutputStream(new FileOutputStream(test));
dos.writeDouble(1000);
dos.close();

具体来说,File.createNewFile()调用是对时间和空间的毫无意义的浪费,而ByteBuffers和字节数组的所有混乱都可以通过DataOutputStream.

更简单地完成

但是,您遇到的问题是您的硬件C double显然与您的Java double写入文件的格式不同。请注意,与您提出的一些评论相反,这确实是可能的,因为C不必遵守IEEE-754的位格式或字节顺序。

有关详细信息,请参阅here