[英]Java read binary file (unsigned long long)
我想将C代码转换为Java。 它读取一个二进制文件:
int main(int argc, char**argv)
{
FILE *fd;
unsigned long trameNumber = 0;
unsigned long long INDEX;
fd = fopen(argv[1],"rb");
if (fd == NULL)
{
printf("Usage %s [File]\n", argv[0]);
exit(1);
}
fread(&INDEX, sizeof(INDEX),1, fd);
printf("INDEX %llx\n",INDEX);
trameNumber++;
while (fread(&INDEX, sizeof(INDEX),1, fd) != 0)
{
printf("INDEX %llx\n",INDEX);
trameNumber++;
}
fclose(fd);
printf("%lu", trameNumber);
return 0;
}
此代码的输出如下所示:
INDEX 0
INDEX 9800000000000000
INDEX 1801000000000000
INDEX 5001000000000000
INDEX b801000000000000
这是我的Java代码。 我试图用BigInteger
做到这一点:
public static final int DATA_BYTE_LENGHT = 8;
public void readBinary(final String readFilePath)
{
// A 8 byte buffer = 64 bits
ByteBuffer byteBuffer = ByteBuffer.allocate(DATA_BYTE_LENGHT);
// Those channels will be used to read/write files
FileChannel channelFileInput = null;
BigInteger bigIndex = null;
try {
// File to read
final File fileRead = new File(readFilePath);
// Channel used to read the file.
channelFileInput = new FileInputStream(fileRead).getChannel();
byteBuffer.put(new byte[DATA_BYTE_LENGHT]);
byteBuffer.rewind();
// While the file has content
while( channelFileInput.read(byteBuffer) != -1 ) {
byteBuffer.rewind();
// Big integer positive
bigIndex = new BigInteger(1, byteBuffer.array());
byteBuffer.rewind();
System.out.println("INDEX "+bigIndex.toString(16));
// Clear the buffer
byteBuffer.put(new byte[DATA_BYTE_LENGHT]);
byteBuffer.rewind();
}
} catch(FileNotFoundException e) {
System.err.println("The file cannot be read: "+e.getMessage());
} catch(Exception e) {
System.err.println(e.getMessage());
} finally {
// Close file connections
IOUtils.closeQuietly(channelFileInput);
}
}
但是, read()
似乎无法正确读取文件。 因为输出是:
INDEX 0
INDEX 98
INDEX 118
INDEX 150
INDEX 1b8
可能是流行病吗? 怎么解决呢?
谢谢
BigInteger
构造函数假定使用大端表示,而文件中的数据似乎存储在小端。 要解决此问题,您可以反转获取的数组中的字节,或者使用ByteBuffer
order
方法设置字节序并使用long
数据类型:
// before loop
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
// in loop
long bigIndex = byteBuffer.getLong();
byteBuffer.rewind();
System.out.println("INDEX "+Long.toHexString(bigIndex));
但是,Java的long
数据类型已签名。 取决于您以后对数字的处理方式,这可能是问题,也可能不是问题。
更新:如果必须使用BigInteger
,则可以像我之前所说的那样反转字节数组,或者使用long
读取数字,然后更正符号:
BigInteger bi = BigInteger.valueOf(bigIndex & ~Long.MIN_VALUE);
if (bigIndex < 0) bi = bi.setBit(63);
Java将所有原始数据类型定义为使用big endian。 如果您使用的是x86(Windows,Linux或OSX)平台,则您的计算机可能会使用Little Endian。 疲劳可能是您痛苦的原因。 您可以使用掩码和移位操作反转字节顺序来解决问题。 这个答案实际上是在这个答案中给出的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.