首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java8如何读取文件两次并修复java.io.IOException:流关闭

Java8如何读取文件两次并修复java.io.IOException:流关闭
EN

Stack Overflow用户
提问于 2020-11-05 01:29:57
回答 1查看 303关注 0票数 0

我尝试读取文本文件两次,以计算平均值(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()方法,但是抛出了一个不支持这些方法的异常。

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

有人知道我如何实现它吗?

代码语言:javascript
复制
    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;
        }
    }
代码语言:javascript
复制
    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));
       }

    }   
EN

回答 1

Stack Overflow用户

发布于 2020-11-27 00:46:22

我相信你不应该对资源使用try。它在其BufferedReader上调用close,这会导致关闭所有封装的读取器。即关闭BufferedReaderReaderFileReader

当您在App::runProcess中调用calcAverage时,它会关闭所有读取器。然后,当在下一行调用processFile时,您将尝试读取closed Reader

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64684948

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档