Java 8如何读取两次文件并修复Java.io.IOException:Stream closed



我试图读取一个文本文件两次,以计算平均值(calcAverage(,然后对平均值进行过滤以获得结果列表(processFile(。当运行第二个步骤时,异常
java.io.UncheckedIOException: java.io.IOException: Stream closed被抛出。

下面是我失败代码的简化版本和驱动代码的单元测试。

类型为Reader的参数(source(从单元测试传递到App,并且是文本文件的FileReader。我不知道如何从Reader对象访问File处理程序(或文件名(来重新打开它——我已经尝试在应用程序中实现了这一点,这将解决问题。runProcess (Reader source)的方法签名不能更改,但其他方法签名可以更改。

我正在使用一个try-with-resources块来打开Reader对象并读取它——然后它会自动关闭——这一切都很好。我只需要一种从Reader重新打开文件的方法来执行pass-2的过滤。

我从类似的问题中读到,BufferedReader就像一个迭代器,你只能读一次。

我已经尝试在source对象上使用mark()reset()方法,但这引发了一个不支持这些方法的异常。

我可以将整个文件读取到List对象中,然后使用它来计算这两个步骤,但我不知道我的文件会有多大,所以如果可能的话,我想尝试使用下面的方法找到解决方案。

有人知道我该怎么做吗?

public class App {

public static void runProcess(Reader source) {
Collection<?> col = calcAverage(source);
processFile(source).forEach(x -> System.out.println(x));
}

private static Collection processFile(Reader source)  {
Collection<?> col = processFile(source, ((BufferedReader reader) -> reader.lines()
.skip(1)
.collect(Collectors.toList()))
);
return col;
}

private static Collection<?> calcAverage(Reader source) {
Collection<?> col = processFile(source, ((BufferedReader reader) -> reader.lines()
.skip(1)
.collect(Collectors.toList())));
return col;
}

private static Collection<?> processFile(Reader source, BufferedReaderProcessor p){
try (BufferedReader reader = new BufferedReader(source)) {
return p.process(reader);
}catch (FileNotFoundException f){
f.printStackTrace();
return null;
}catch (IOException e){
e.printStackTrace();
return null;
}catch (Exception ex){
ex.printStackTrace();
return null;
}
}

@FunctionalInterface
public interface BufferedReaderProcessor {
Collection<?> process(BufferedReader b) throws IOException;
}
}

public class AppTest {
@Test
public void shouldReadFileTwice() throws FileNotFoundException {
App.runProcess(openFile("src/main/java/functions/example4/resources/list-of-fruits"));
}
private static Reader openFile(String filename) throws FileNotFoundException {
return new FileReader(new File(filename));
}
}   

我认为您不应该使用try with resources。它在其BufferedReader上调用close,导致所有封装的读取器关闭。即关闭BufferedReaderReaderFileReader

当您在App::runProcess中调用calcAverage时,它会关闭所有读卡器。然后,在下一行调用processFile时,您正试图读取已关闭的Reader

相关内容

  • 没有找到相关文章