Java8流文件,如何控制文件的关闭?

Java8流文件,如何控制文件的关闭?,第1张

Java8流文件,如何控制文件的关闭?

关于使用FileReader的一般注意事项:FileReader在内部使用FileInputStream,它会覆盖

finalize()
并且因此不建议使用它对垃圾回收的影响,尤其是在处理大量文件时。

除非您使用的是Java 7之前的Java版本,否则应改用java.nio.files API,使用以下命令创建BufferedReader

 Path path = Paths.get(filename); BufferedReader br = Files.newBufferedReader(path);

因此,流管道的开始应看起来更像

 filenames.map(Paths::get)          .filter(Files::exists)          .map(p -> {        try { return Optional.of(Files.newBufferedReader(p));        } catch (IOException e) { return Optional.empty();        }    })

现在到您的问题:

选项1

保存原件的一种方法

Reader
是使用元组。通常,元组(或其任何n元变体)是处理函数应用程序的多个结果的好方法,因为它是在流管道中完成的:

class ReaderTuple<T> {   final Reader first;   final T second;   ReaderTuple(Reader r, T s){     first = r;     second = s;   }}

现在,您可以将FileReader映射到元组,其中第二项是您当前的流项目:

 filenames.map(Paths::get)  .filter(Files::exists)  .map(p -> {        try { return Optional.of(Files.newBufferedReader(p));        } catch (IOException e) { return Optional.empty();        }    })   .filter(Optional::isPresent)  .map(Optional::get)  .flatMap(r -> new ReaderTuple(r, yourOtherItem))  ....  .peek(rt -> {    try {       rt.first.close()  //close the reader or use a try-with-resources    } catch(Exception e){}   })  ...

这种方法的问题在于,只要在flatMap和peek之间执行流期间发生未经检查的异常,读者就可能不会关闭。

选项2

使用元组的另一种方法是将需要阅读器的代码放在try-with-resources块中。这种方法的优势在于您可以控制所有读者。

范例1:

 filenames.map(Paths::get)  .filter(Files::exists)  .map(p -> {        try (Reader r = new BufferedReader(new FileReader(p))){ Stream.of(r) .... //put here your stream pre that uses the stream        } catch (IOException e) { return Optional.empty();        }    }) //reader is implicitly closed here .... //terminal operation here

范例2:

filenames.map(Paths::get)  .filter(Files::exists)  .map(p -> {        try { return Optional.of(Files.newBufferedReader(p));        } catch (IOException e) { return Optional.empty();        }    })  .filter(Optional::isPresent) .map(Optional::get) .flatMap(reader -> {   try(Reader r = reader) {      //read from your reader here and return the items to flatten   } //reader is implicitly closed here  })

示例1的优点是读者肯定会关闭。示例2是安全的,除非您在创建读取器和try-with-resources块之间添加更多内容,否则可能会失败。

我个人将使用示例1,并将访问读者的代码放在单独的函数中,以使代码更易读。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5561859.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存