Java 如何从非常大的文件中读取行号x到(x+;y)

Java 如何从非常大的文件中读取行号x到(x+;y),java,java-8,stream,java-stream,Java,Java 8,Stream,Java Stream,我有一个非常大的文本文件,其中每一行都必须被解析。 我想读取x到x+100000行,并将每行添加到一个列表中,以便List.size startine&&iteration=最大行数){ 打破 } } }捕获(例外e){ 抛出新的FileReaderException(“未能读取“+inputFile.getAbsolutePath(),e”的行“+iteration+”); } }捕获(FileNotFoundException e1){ 抛出新的FileReaderException(“找不

我有一个非常大的文本文件,其中每一行都必须被解析。 我想读取x到x+100000行,并将每行添加到一个列表中,以便List.size startine&&iteration=最大行数){ 打破 } } }捕获(例外e){ 抛出新的FileReaderException(“未能读取“+inputFile.getAbsolutePath(),e”的行“+iteration+”); } }捕获(FileNotFoundException e1){ 抛出新的FileReaderException(“找不到文件“”+inputFile.getAbsolutePath()+”。”,e1); }捕获(IOE1异常){ 抛出新的FileReaderException(“无法读取文件””+inputFile.getAbsolutePath()+“.”,e1); } 返回结果; } 在试图找出如何跳过行的时候,我遇到了Java8流读取文件的方式,下面的代码就是我尝试用这种方式处理它的代码。这一款在第一次通话时也非常有效,返回了前100k条线路。对于第二个调用,从第100k+1行开始,返回“java.lang.IllegalStateException:流已经被操作或关闭”。另外,我只想读取x到x+100k行,然后返回,而不是循环文件的所有行。我对这个流对象还不熟悉,但使用它似乎可以提供一个解决方案

public List<MyModel> retrieve(File inputFile, int startLine, String checksum) throws DaoException {
    List<MyModel> result = new ArrayList<>();

    try (Stream<String> lines = Files.lines(inputFile.toPath(), Charset.defaultCharset())) {
        lines.skip(startLine);
        lines
        .filter(line -> result.size() <= 100000)
        .forEach(line -> {
            result.add(this.fileReader.populateMyModel(line));
            if (result.size() % 10000 == 0) {
                LOGGER.info("result size: " + result.size());
            }
        });
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return result;
}
public List retrieve(文件inputFile、int-startine、字符串校验和)引发异常{
列表结果=新建ArrayList();
try(streamlines=Files.lines(inputFile.toPath(),Charset.defaultCharset()){
行。跳过(行);
线
.filter(行->结果.size(){
add(this.fileReader.populateMyModel(行));
if(result.size()%10000==0){
LOGGER.info(“结果大小:+result.size());
}
});
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
返回结果;
}
任何建议都会很有帮助。

当你写:

lines.skip(startLine)
您创建了一个新流,但没有保存对它的引用,因此您将丢失该操作

我猜你想要的是:

return lines.skip(startLine)
            .limit(100000)
            .map(fileReader::populateMyModel)
            .collect(toList());

您应该使用
skip().filter(…)…
,skip返回一个新的流,并且您不能重复使用一个已消费的流。@holi java-虽然我的问题中提到了这个例外,但这个链接并没有说明如何从文件中读取一组特定的行号,这就是这个问题的内容。嗯,如果你认为这是合理的。我把它还原了。我想,在我将你的答案标记为重复之前,我是第一个投票的人。我只想告诉你,这里有完整详细的答案。我按照你的指导修改了代码,但仍然出现了OutOfMemory错误。即使我将行数减少到10000
result=lines.skip(startLine).limit(10000).map(fileReader::populateImportShippingNetRecord).collect(Collectors.toList())我在同事的电脑上运行了相同的修复程序,效果很好。它仍然减慢了速度,但从未耗尽内存。我现在必须检查我的系统,但这似乎是解决办法。谢谢。阅读100000行并存储它们不会占用太多内存(除非每行有1000个字符)。问题可能是由于行太长或您尚未显示的populateImportShippingNetRecord方法造成的。您可以使用探查器找出内存的使用位置。事实证明,这是循环中arraylist的错误实例化。
return lines.skip(startLine)
            .limit(100000)
            .map(fileReader::populateMyModel)
            .collect(toList());