本机代码:
使用fwrite()。
写编号27int main()
{
int a = 27;
FILE *fp;
fp = fopen("/data/tmp.log", "w");
if (!fp)
return -errno;
fwrite(&a, 4, 1, fp);
fclose();
return 0;
}
使用datainputstream.readint()读取数据(27):
public int readIntDataInputStream(void)
{
String filePath = "/data/tmp.log";
InputStream is = null;
DataInputStream dis = null;
int k;
is = new FileInputStream(filePath);
dis = new DataInputStream(is);
k = dis.readInt();
Log.i(TAG, "Size : " + k);
return 0;
}
o/p
Size : 452984832
好吧,十六进制是 0x1b000000
0x1b
是27
。但是ReadInt()在我的本地编码写作时,将数据读成大元素。。因此,代替0x0000001b
,我得到0x1b000000
。
我的理解正确吗?有人以前遇到过这个问题吗?
来自javadoc的readInt()
:
此方法适用于读取字节
编写的字节writeInt
接口DataOutput
如果您想阅读C程序写的内容,则必须使用java.nio
中的设施来进行字节交换。我从来没有这样做,但是我相信您会将数据读为ByteBuffer
,将缓冲区的订单设置为ByteOrder.LITTLE_ENDIAN
,然后在ByteBuffer
上创建IntBuffer
视图,如果您有一个值数组,或者仅将ByteBuffer#getInt()
用于单个值。
除此之外,我同意@EJP的观点,即数据的外部格式应该是最大兼容性的大范围。
您的代码中有多个问题:
-
您假设
int
的大小为4
,不一定是正确的,并且由于您想处理32位INT,因此应使用int32_t
或uint32_t
。 -
您必须在二进制中打开文件,以可靠地编写二进制数据。上面的代码将在Windows上失败,以减少琐碎的输出。使用
fopen("/data/tmp.log", "wb")
。 -
您必须处理endianness。您正在使用该文件在不同的平台之间交换数据,这些平台可能具有不同的本地endianness和/或Endian特定的API。Java似乎使用Big-Endian,又名网络字节顺序,因此您应该使用
hton32()
实用程序函数转换C平台上的值。这不太可能对PC端的性能产生重大影响,因为此功能通常是内联扩展的,可能是单个指令,并且大部分时间都会花在等待I/O。
这是代码的修改版本:
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint32_t a = hton32(27);
FILE *fp = fopen("/data/tmp.log", "wb");
if (!fp) {
return errno;
}
fwrite(&a, sizeof a, 1, fp);
fclose();
return 0;
}