我想用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文件查看器中读取。
我是否使用正确的类来读取二进制数据?我错过了什么吗?我试图避免使用外部库,因为我只是想读取应该非常简单的文件。
答案 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
}