如何解决Java 8如何两次读取文件并修复java.io.IOException:流已关闭
我试图读取一个文本文件两次,以计算平均值(calcAverage
),然后对平均值进行过滤以获取结果列表(processFile
)。在执行第二步时,出现异常,java.io.UncheckedIOException: java.io.IOException: Stream closed
被抛出。
下面是我失败的代码的简化版本和用于驱动代码的单元测试。
类型source
的参数(Reader
)从单元测试传递到App
,并且是文本文件的FileReader
。我不知道如何从File
对象访问Reader
处理程序(或文件名)以重新打开它-我已经尝试在App内部实现此方法,这将解决问题。 runProcess (Reader source)
的方法签名不能更改-但是其他方法签名可以更改。
我正在使用try-with-resources
块打开Reader对象并通过它读取它-然后自动关闭-一切都很好。我只需要一种从Reader
重新打开文件以执行pass-2过滤的方法。
我从类似的问题中了解到,BufferedReader
就像一个迭代器,您只能读取一次。
我尝试在mark()
对象上使用reset()
和source
方法,但这引发了一个例外,即不支持这些方法。
我可以将整个文件读取到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));
}
}
解决方法
我相信您不应该尝试使用资源。它在其BufferedReader上调用close
,导致所有封装的阅读器都关闭。
即它会关闭BufferedReader
,Reader
和FileReader
。
在calcAverage
中调用App::runProcess
时,它将关闭所有阅读器。然后,您尝试在下一行调用Reader
时读取已关闭的processFile
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。