二进制文件无法正确读取Java

时间:2014-03-20 01:58:24

标签: java

我想用Java阅读一个二进制文件(实际上是一个dBF)。我正在使用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,并使用格式字符串为十六进制,在所有情况下,它看起来像0xFD。

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

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

2 个答案:

答案 0 :(得分:5)

如果这是二进制文件,请不要使用任何类型的Reader

Reader采用一系列字节并尝试将其解析为中的字符(取决于编码)。

因为这是一个二进制文件,所以会有许多字节序列,这些字节序列是不可翻译的。结果,您将丢失数据......

  

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

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

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

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

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

Obligatory link< - 保持开放并阅读您需要的内容:)此答案中的所有类名都记录在那里。

答案 1 :(得分:0)

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

此外,您不需要bufferedReader。

尝试

 fis = new FileInputStream(source_url);

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