当前位置: 首页 > 知识库问答 >
问题:

流上的终端操作是否关闭源?[副本]

罗浩然
2023-03-14

考虑以下代码:

Path directory = Paths.get(/* some directory */);
Files.list(directory).forEach(System.out::println);

终端操作(如forEach)是否关闭已打开的底层文件?

请参阅文件javadoc的相关部分。列表:

返回的流封装了DirectoryStream。如果需要及时处理文件系统资源,则应使用try-with-resources构造来确保在流操作完成后调用流的close方法。

如果它不调用Stream.close(),那么在生成可维护代码时调用它的最佳替代方案是什么?

共有2个答案

蒙化
2023-03-14

因此,快速检查表明,forEach不会关闭目录流:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * Created for http://stackoverflow.com/q/27381329/1266906
 */
public class FileList {
    public static void main(String[] args) {
        Path directory = Paths.get("C:\\");
        try {
            Stream<Path> list = Files.list(directory).onClose(() -> System.out.println("Close called"));
            list.forEach(System.out::println);
            // Next Line throws "java.lang.IllegalStateException: stream has already been operated upon or closed" even though "Close called" was not printed
            list.forEach(System.out::println);
        } catch (IOException | IllegalStateException e) {
            e.printStackTrace();  // TODO: implement catch
        }

        // The mentioned try-with-resources construct
        try (Stream<Path> list = Files.list(directory)) {
            list.forEach(System.out::println);
        } catch (IOException | IllegalStateException e) {
            e.printStackTrace();  // TODO: implement catch
        }

        // Own helper-method
        try {
            forEachThenClose(Files.list(directory), System.out::println);
        } catch (IOException | IllegalStateException e) {
            e.printStackTrace();  // TODO: implement catch
        }
    }

    public static <T> void forEachThenClose(Stream<T> list, Consumer<T> action) {
        try {
            list.forEach(action);
        } finally {
            list.close();
        }
    }
}

我看到了两个提出的缓解措施:

  1. 使用文件中所述的try-with资源。列表

哪种方法更易于维护可能取决于您需要多少辅助方法。

鲁浩言
2023-03-14

终端操作员不会自动关闭流。考虑以下代码

Stream<Path> list = Files.list(directory).onClose(() -> System.out.println("Closed"));
list.forEach(System.out::println);

这不会打印“关闭”。

但是,以下内容会打印“已关闭”:

try (Stream<Path> list = Files.list(directory).onClose(() -> System.out.println("Closed"))) {
    list.forEach(System.out::println);
}

因此,最好的方法是使用资源试用机制。

 类似资料:
  • 问题内容: 考虑以下代码: 终端操作(如)是否关闭已打开的基础文件? 请参阅Files.list的javadoc的相关部分: 返回的流封装了DirectoryStream。如果需要及时处理文件系统资源,则应使用try-with- resources构造来确保在流操作完成之后调用流的close方法。 如果不调用,那么在生成可维护代码时最好的替代方法是什么? 问题答案: 终端操作员不会自动关闭流。考虑

  • 问题内容: 下面的代码是否需要包装在try-with-resources中,以确保基础文件已关闭? 问题答案: 作为重载方法状态的javadoc 返回的流封装了。如果需要及时处理文件系统资源,则应使用该构造来确保在流操作完成之后调用流的close方法。 所以是的,在语句中包装返回的。(或适当关闭它。)

  • 我想测试一个返回流的方法。 现在,我已经为当somecondition=true时的情况编写了以下测试

  • 阅读后https://www.airpair.com/java/posts/spring-streams-memory-efficiency,我很想从数据库中导出结果,但正如我与一位同事讨论的那样(他在那篇文章中添加了cfr注释),需要记住使用try with resources构造来避免任何内存泄漏。 为什么Java 8库不负责在每次终端操作后关闭流本身(而不必将流实例化包装在资源试用中)

  • 本文向大家介绍golang判断net.Conn 是否已关闭的操作,包括了golang判断net.Conn 是否已关闭的操作的使用技巧和注意事项,需要的朋友参考一下 在多线程的线程里边,用一个线程处理一条连接,如何判断连接已经关闭? 试了一下,如果连接中断,读写会出现这种net.OpError,这个就可以判断是否断开 但是我也不确定有没有更好的方法?如果有的话,希望朋友们不吝赐教 补充:Go --

  • 我一直在网上寻找,我发现没有文章说如何使用Python代码关闭终端。 这是我的代码: 我希望它关闭终端,而不是仅仅结束其进程。我见过其他项目也有这种情况,我也想这样做。有办法吗?谢谢