【问题标题】:Implement fread (readInt) in java在java中实现fread(readInt)
【发布时间】:2020-12-19 23:50:02
【问题描述】:

我正在尝试将读取 C++ 二进制文件的程序转换为 java。该文件采用小端格式。

fread(n, sizeof (unsigned), 1, inputFile);

上面c++的sn-p将1个整数读入整数变量'n'。

我目前正在使用这种方法来完成同样的事情:

public static int readInt(RandomAccessFile inputStream) throws IOException {
    int retVal;
    byte[] buffer = new byte[4];
    inputStream.readFully(buffer);
    ByteBuffer wrapped = ByteBuffer.wrap(buffer);
    wrapped.order(ByteOrder.LITTLE_ENDIAN);
    retVal = wrapped.getInt();
    return retVal;
}

但是这种方法的结果有时与 c++ 示例不同。我无法确定文件的哪些部分导致此方法失败,但我知道确实如此。例如,当读取文件的一部分时,我的 readInt 方法返回 543974774,但 C++ 版本返回 1

有没有更好的方法来读取 Java 中的小端值?还是我的实施中有一些明显的缺陷?任何帮助了解我可能出错的地方,或者我怎样才能以更有效的方式阅读这些值,我们将不胜感激。

更新: 我正在使用 RandomAccessFile,因为我经常需要 RandomAccessFile 在 java 中提供的 fseek 功能

【问题讨论】:

  • 嗯,是的,完全正确。
  • 您读取的值是有符号还是无符号?
  • 我认为您需要同时运行 Java 和 C++ 程序,在读取它们时打印值以及文件中的偏移量,然后找到它们不同的第一个点。
  • 另外,C++ 中的unsigned 不一定必须是 4 个字节。 C++ 不是 Java,这些类型的大小是固定的。可以肯定的是,在 C++ 端,使用int32_tuint32_t,而不是unsigned
  • getInt 返回的值是有符号的,因此可能会给您带来问题。我怀疑您的问题不完全在于readInt,还在于您在文件中的位置。

标签: java file io endianness


【解决方案1】:

543974774 是十六进制的 206C6576。

地球上没有将 206C6576 变成“1”的字节序。因此,问题在于您没有阅读您认为正在阅读的内容:如果 C 代码正在读取 4 个字节(甚至是一个变量,未知字节数)并将其转换为“1”,那么您的 java 代码是'不读取相同的字节 - 您的 C 代码和 java 代码不同步:在某些时候,您的 C 代码读取,例如 2 个字节,而您的 java 代码读取 4 个字节,反之亦然。

问题不在于您的 readInt 方法 - 每次都能正确完成工作。

【讨论】:

  • 绝对正确。在阅读我认为是问题的区域之前,我正在寻找错误的位置,因为我正在阅读带符号而不是无符号的 int。
猜你喜欢
  • 2011-04-25
  • 2016-07-21
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
  • 1970-01-01
  • 2011-02-12
相关资源
最近更新 更多