【问题标题】:Binary files not reading correctly with Java使用 Java 无法正确读取二进制文件
【发布时间】:2014-03-20 01:58:24
【问题描述】:

我有一个二进制文件(实际上是一个 dBF),我想用 Java 读取。我正在使用 FileInputStream 和 BufferedReader,然后将所需的字节读取为 char[]。

    FileInputStream fis;

    char[] header = new char[32];

    try {
        fis = new FileInputStream(source_url);

        BufferedReader br;
        String line;

        br = new BufferedReader(new InputStreamReader(fis, Charset.forName("UTF-8")));
        br.read(header);
        ....

问题是我读入数组的值并不总是文件中的值。例如,值 0xE1 被读取为 0xFD。我尝试了不同的字符集,没有任何变化,并将值读取为各种类型的 long、int、byte,并使用格式字符串转为 hex,在所有情况下它看起来都像 0xFD。

这些值是明确错误的,我可以在 C++ 程序中正常读取,因为它可以理解无符号整数,并且可以在 hex 文件查看器中读取。

我是否使用正确的类来读取二进制数据?我错过了什么吗?我试图避免使用外部库,因为我只是想读取应该非常简单的文件。

【问题讨论】:

  • 如果它是一个二进制文件,那么它是 NOT utf,并且文件中各种完全可以接受的字节序列将被误解为多字节 UTF-8 字符。
  • 名为XxxxReader 的类用于阅读文本。名为XxxxxInputStream 的类用于读取二进制数据。

标签: java


【解决方案1】:

如果这是一个二进制文件,请勿使用任何类型的Reader

Reader 获取一个字节序列并尝试将其解码为字符尽其所能(这取决于编码)。

由于这是一个二进制文件,会有很多个字节序列无法翻译。结果,您将丢失数据...

我可以在 C++ 程序中正常阅读,因为它可以理解无符号整数,并且可以在十六进制文件查看器中阅读。

这与无符号完全无关。 Java 的原始整数类型(char 除外,见下文)是有符号的,是的;但它们仍然是位。没有符号位这样的东西。

请注意,在 Java 中,char 不是 byte。它是一个 16 位无符号整数,专门用于保存字符。

要高效读取二进制数据,请使用Files.newByteChannel()FileChannel.open()。如果您愿意,可以使用后者将文件映射到内存中...另请参阅Files.readAllBytes()

特别是如果您的二进制数据是结构化的,请使用FileChannel.open(),因为FileChannel 实现ScatteringByteChannel

Obligatory link

【讨论】:

  • 非常感谢。我一直在使用 java 6,它似乎没有导入 java.nio.file.Files。仍然需要将 java 认为的负数转换为无符号整数,但我可以忍受。
  • 您“一直”在使用?而现在呢?你应该尽可能快地走 7;它现在已经很老了,因为 Java 8 已经过时了
【解决方案2】:

如果您正在读取二进制数据,那么您不希望将其转换为 UTF-8

你也不想要一个 bufferedReader。

试试

 fis = new FileInputStream(source_url);

 while (br = fis.read () != -1) {
    // save data to byte array
 }

【讨论】:

  • 我认为您不需要InputStreamReader,但即便如此,您也应该使用读取字节数组的其他读取重载来提高效率。
  • eeks 我错过了 - 将修复
猜你喜欢
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 2021-07-26
  • 2011-07-25
  • 1970-01-01
  • 2019-05-16
相关资源
最近更新 更多