如何从FileInputStream

时间:2019-01-24 14:39:04

标签: java fileinputstream

我正在制作有关数据压缩的项目(使用霍夫曼算法)。该项目仍在修订中。我遇到了一个非常有趣的问题。我需要从二进制文件中逐字节读取。我有这个文件FileInputHelper,它可以实现几种方法:

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,我会认为文件已结束。但事实并非如此。有什么办法可以解决这个问题?我可以得到EOFException吗?如果我的代码不正确,我想听听您的建议。

2 个答案:

答案 0 :(得分:1)

这就是InputStream.read()在实际读取int时声明返回类型byte的原因。仅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

您可能不想在char方法中使用public char read(),因为char是未签名的并且不能保存-1。返回int并遵循通常的约定更具可读性。

答案 1 :(得分:0)

问题在于List<BOMItemSummary> bomItems = new List<BOMItemSummary>(); ... var bomItemsForId = bom.BOMLineItems.Select(bomItem => new BOMItemSummary { ... }); bomItems.AddRange(bomItemsForId); 是未签名的,而char是已签名的。基本上,哪里是一个特定字符(byte),当转换为字节时它映射到0xffff。这也是为什么InputStream上的-1方法返回整数的原因,即使您正在获取字节或char。

处理此问题的一种方法是检查read()是否返回read(),然后再将其转换为字节或char。然后,如果-1返回read(),则可以引发EOFException并捕获该异常。例如

-1

但是,捕获异常并非旨在指示操作已正常完成。一种避免这种情况的处理方法是缓冲一个字符/字节,并添加一个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()方法,这将对文件的读取产生影响,因此请记住这一点。