返回带有文件源的对象流

Returning an Object stream with a file source

我目前正在使用一种方法实现一个接口,该方法 returns 对象流。对于实现,我正在从文件中读取并对行进行反序列化。不幸的是,这意味着我无法关闭 BufferedReader/FileReader,因为我需要它为流的消费者打开。有人 运行 遇到过类似的问题吗?您是如何做到 it/is 确实有任何安全的方法可以做到这一点而不会导致资源未清理的?该文件很大,所以我不想将其全部读入内存。

public class ObjectStreamerImpl implements ObjectStreamer {
    @Override
    public Stream<Object> getObjectStream() {
        return new BufferedReader(new FileReader(new File("my/file/path.txt"))).lines()
            .map(line -> convertToObject(line));
    }
}

您必须跟踪 BufferedReader 以便以后可以将其关闭。一种方法是使 ObjectStreamerImpl 可关闭。

class ObjectStreamerImpl implements ObjectStreamer, Closeable {

    private BufferedReader reader;

    public ObjectStreamerImpl() throws FileNotFoundException {
        reader = new BufferedReader(new FileReader("my/file/path.txt"));
    }

    @Override
    public Stream<Object> getObjectStream() {
        return reader.lines().map(line -> convertToObject(line));
    }

    @Override
    public void close() throws IOException {
        reader.close();
    }
}

然后使用 try-with-resources 块。

try (ObjectStreamerImpl streamer = new ObjectStreamerImpl()) {
    // streamer.getObjectStream()...
}

请注意,StreamAutoClosable,因此可以使用 try-with 资源有效处理分配给流的任何资源:

try(var stream = getObjectStream()) {
    // do work with stream here
}

然后修复 getObjectStream 以避免使用 BufferedReader - 没有必要,您可以更改为 PathFiles.lines():

public Stream<Object> getObjectStream() throws IOException {
    return Files.lines(Path.of("my/file/path.txt"))
        .map(line -> convertToObject(line));
        // Or .map(this::convertToObject)
}