我想将 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读取二进制文件(unsigned long long),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20121623/