首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Files.lines :关闭流

Files.lines :关闭流
EN

Stack Overflow用户
提问于 2020-12-23 14:30:46
回答 3查看 300关注 0票数 1

我需要关闭由Files.lines创建的流:

代码语言:javascript
运行
复制
  Map<String, Long> wordCounts =
        Files.lines(fileP, Charset.forName("UTF-8"))
        .map(line -> line.replaceAll("[.?!]$"," % "))
        .flatMap(line -> pattern.splitAsStream(line))
        .collect(Collectors.groupingBy(String::toLowerCase,
                TreeMap::new, Collectors.counting()));

我该怎么做?

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-12-23 14:38:22

Files.lines实现AutoCloseable,因此您可以在资源中使用try-catch

代码语言:javascript
运行
复制
try(Stream<String> fileLines = Files.lines(fileP, Charset.forName("UTF-8"))){

    Map<String, Long> wordCounts = fileLines.map(line -> line.replaceAll("[.?!]$"," % "))
                                      .flatMap(line -> pattern.splitAsStream(line))
                                      .collect(Collectors.groupingBy(String::toLowerCase,
                                               TreeMap::new, Collectors.counting()));

}catch(Exception e){
    e.printStackTrace();
}

执行try块后,它会自动调用fileLines.close()

P.S.:阅读rzwitserloot的答案,它包含有用的信息。

票数 2
EN

Stack Overflow用户

发布于 2020-12-23 14:38:03

根据Javadoc

需要对文件系统资源进行..If的及时处理,应该使用“使用资源进行尝试”结构来确保流操作完成后调用流的关闭方法。

代码语言:javascript
运行
复制
try (Stream<String> stream = Files.lines(fileP, Charset.forName("UTF-8"))) {
    stream.map(line -> line.replaceAll("[.?!]$"," % "))
      ...//rest of code here
}
票数 2
EN

Stack Overflow用户

发布于 2020-12-23 14:38:53

流的API不是以这种方式使用的。不幸的是,溪流/功能/可选等是当前的‘味道’,有大量的狂热者和改信者,他们已经找到了他们的宗教,现在正在积极地试图改变他们所能找到的每一个灵魂。正如您所写的,这些代码在他们看来是“干净的”(在旁观者眼中是一个术语,但我可以看到这种代码风格对许多人来说是多么的好),这已经扩展到那些经常犯错误的甲骨文教程中。然而,javadoc明确说明了您应该如何使用流。这不是怎么回事。

来自Files.lines的javadoc

返回的流封装一个Reader。如果需要及时处理文件系统资源,则应使用“使用资源进行尝试”结构来确保流操作完成后调用流的关闭方法。

这是一句轻描淡写的话;“如果需要及时处理文件系统资源”,这是一种有趣的说法:“如果您希望您的VM不成为边缘无用的,因为它耗尽了文件句柄,并且由于无法打开jar文件在某些类中读取而面临崩溃的风险”。

因此,您必须按它说的做:将它们封装在“使用资源”的尝试块中。任何Stream都可以如此包装(因为Stream实现了AutoClosable --它有一个close()方法):

代码语言:javascript
运行
复制
Map<String, Long> wordCounts;
try (var stream = Files.lines(fileP)) {
    wordCounts = stream
      .map(...)
      .flatMap(...)
      .collect(...);
}

注意:这里不需要指定UTF-8;与java核心运行时中的大多数基本方法不同,所有隐式将字节转换为字符的Files方法(反之亦然)都将使用UTF-8,如果您没有指定编码。

NB2:流上的终端操作(如.collect )在完成时,最终会关闭底层流。问题是:如果您的一个.map操作最终抛出,您的流将保持未关闭状态。

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

https://stackoverflow.com/questions/65425961

复制
相关文章

相似问题

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