Java 如何从FileInputStream获取EOFEException
我正在做一个关于数据压缩的项目(使用哈夫曼算法)。该项目仍在修订中。我遇到了一个非常有趣的问题。我需要从二进制文件中逐字节读取。我得到了这个文件FileInputHelper,它实现了几个方法:Java 如何从FileInputStream获取EOFEException,java,fileinputstream,Java,Fileinputstream,我正在做一个关于数据压缩的项目(使用哈夫曼算法)。该项目仍在修订中。我遇到了一个非常有趣的问题。我需要从二进制文件中逐字节读取。我得到了这个文件FileInputHelper,它实现了几个方法: import java.io.IOException; public class FileInputHelper implements Closeable { private FileInputStream fileInputStream; private BufferedReader
import java.io.IOException;
public class FileInputHelper implements Closeable {
private FileInputStream fileInputStream;
private BufferedReader fileBufferedReader;
public FileInputHelper(File file) throws IOException {
fileInputStream = new FileInputStream(file);
fileBufferedReader = new BufferedReader(
new InputStreamReader(fileInputStream));
}
public byte readByte() throws IOException {
return (byte)fileInputStream.read();
}
public char read() throws IOException {
return (char)fileInputStream.read();
}
public String readLine() throws IOException {
return fileBufferedReader.readLine();
}
@Override
public void close() throws IOException{
fileInputStream.close();
}
}
但是当二进制文件结束时,方法应该返回-1。当然,应该如此。但是有一些测试,其中有字节,它们等于-1,但不是最后一个。
正如你所理解的,这是非常关键的。如果在中间我读到-1,我会认为文件已经结束了。但事实并非如此。有没有办法解决这个问题?我能得到EOFEException吗?如果我的代码不好,我想听听你的建议。这就是为什么
InputStream.read()
在实际读取byte
时声明返回类型int
。只有int
的低位字节用于数据。如果您读取-1
字节,则它将返回255
,您必须手动将其向下转换为byte
ByteArrayInputStream in = new ByteArrayInputStream(new byte[]{1, 0, -1});
int read;
while ((read = in.read()) > -1) {
System.out.println("As int: " + read + ", as byte: " + (byte) read);
}
将输出:
As int: 1, as byte: 1
As int: 0, as byte: 0
As int: 255, as byte: -1
您可能不想在
public char read()
方法中使用char
,因为char
没有签名,无法保存-1
。返回int
并遵循通常的惯例更具可读性。问题是char
是无符号的,而byte
是有符号的。基本上,其中是一个特定字符(0xffff
),当转换为字节时,该字符映射到-1
。这也是InputStream上的read()
方法返回整数的原因,即使您得到的是字节或字符
处理此问题的一种方法是在将其转换为字节或字符之前检查read()
是否返回-1
。然后,如果read()。e、 g
int cur = fileInputStream.read();
if(cur == -1) {
throw new EOFException("End of input reached");
}else {
return (char) cur;
}
但是,捕获异常并不是用来表示操作已正常完成的一种方式。一种避免这种情况的方法是缓冲字符/字节,并添加available()
方法,如下所示
public class FileInputHelper implements Closeable {
private FileInputStream fileInputStream;
private BufferedReader fileBufferedReader;
private int next;
public FileInputHelper(File file) throws IOException {
fileInputStream = new FileInputStream(file);
fileBufferedReader = new BufferedReader(
new InputStreamReader(fileInputStream));
next = fileInputStream.read();
}
public byte readByte() throws IOException {
int cur = next;
next = fileInputStream.read();
if(cur == -1) {
throw new IOException("End of file reached");
}
return (byte) cur;
}
public char read() throws IOException {
int cur = next;
next = fileInputStream.read();
if(cur == -1) {
throw new IOException("End of file reached");
}
return (char) cur;
}
public String readLine() throws IOException {
return fileBufferedReader.readLine();
}
@Override
public void close() throws IOException{
fileInputStream.close();
}
// Returns true if there are more chars / bytes to read.
public boolean available() {
return next != -1;
}
}
如果同时使用read()
/readByte()
和readLine()
方法,则文件的读取方式会出现问题,因此请记住这一点。提示:InputStream
返回int
:它可以返回从-1到255的值(好吧,它也可以返回short
,但它不返回)。如果一个字节是-1,那么它以前是255。好的。这样得到文件结尾和只得到-1有什么区别呢?byte
-1被读取为正int
255。int
-1是流的结尾。