具有倒带()/重置()功能的java文件输入

2022-09-01 03:30:59

我需要编写一个函数来接收某种输入流的东西(例如 InputStream 或 FileChannel),以便分两次读取一个大文件:一次用于预先计算某些容量,另一次用于执行“实际”工作。我不希望整个文件一次加载到内存中(除非它很小)。

是否有适当的 Java 类提供此功能?FileInputStream 本身不支持 mark()/reset()。我认为 BufferedInputStream 确实如此,但我不清楚它是否必须存储整个文件才能执行此操作。

C语言非常简单,你只需要使用fseek(),ftell()和rewind()。:-(


答案 1

我认为引用FileChannel的答案已经标记好了。

下面是封装此功能的输入流的示例实现。它使用委派,因此它不是真正的FileInputStream,但它是一个InputStream,这通常就足够了。如果这是一项要求,也可以同样扩展FileInputStream。

未经测试,使用风险自负:)

public class MarkableFileInputStream extends FilterInputStream {
    private FileChannel myFileChannel;
    private long mark = -1;

    public MarkableFileInputStream(FileInputStream fis) {
        super(fis);
        myFileChannel = fis.getChannel();
    }

    @Override
    public boolean markSupported() {
        return true;
    }

    @Override
    public synchronized void mark(int readlimit) {
        try {
            mark = myFileChannel.position();
        } catch (IOException ex) {
            mark = -1;
        }
    }

    @Override
    public synchronized void reset() throws IOException {
        if (mark == -1) {
            throw new IOException("not marked");
        }
        myFileChannel.position(mark);
    }
}

答案 2

如果从 中获取关联的,则可以使用 position 方法将文件指针设置为文件中的任意位置。FileChannelFileInputStream

FileInputStream fis = new FileInputStream("/etc/hosts");
FileChannel     fc = fis.getChannel();


fc.position(100);// set the file pointer to byte position 100;

推荐