在O(1)中打开Scala / java中的文件打开文件描述符
看起来,nio的.list返回一个流,当被消耗时,每个文件迭代一个文件描述符,直到.close在整个流中被调用.这意味着具有超过1,000个文件的数据目录可以轻松刷新普通的ulimit值.这种文件描述符累积的整体效果在处理嵌套遍历时进一步加剧.
除了向OS文件列表命令产生调用以外,还可以替代大型目录的文件进行迭代?如果迭代一个大目录的文件,那么文件描述符将只能按照当前迭代的文件进行维护,这是正确的流语义所暗示的. 编辑: list返回一个java.nio.file.Path的Java Stream在处理流时,哪个api调用将用于关闭流中的每个项目,而不是仅在整个流关闭时才能进行精简迭代?在scala中,这可以很容易地使用api包装从更好的文件,从here导致. 解决方法
当我没有关闭流时,我遇到了同样的问题(在Windows Server 2012 R2上).我重复遍历的所有文件都以读取模式打开,直到JVM关闭.但是,它并没有发生在Mac OS X上,并且由于流依赖于与FileSystemProvider和DirectoryStream的操作系统相关的实现,我认为该问题也可以依赖于操作系统.
相对于@Ian McLaird的评论,在
返回的流是DirectoryStream,Javadoc说:
我的解决方案是遵循建议并使用try-with-resources构造 try (Stream<Path> fileListing = Files.list(directoryPath)) { // use the fileListing stream } 当我正确关闭流(使用上面的try-with-resources构造)时,文件句柄立即被释放. 如果您不关心将文件作为流传输,或者您可以将整个文件列表加载到内存中并将其自身转换为流,则可以使用IO API: File directory = new File("/path/to/dir"); File[] files = directory.listFiles(); if (files != null) { // 'files' can be null if 'directory' "does not denote a directory,or if an I/O error occurs." // use the 'files' array or convert to a stream: Stream<File> fileStream = Arrays.stream(files); } 我没有遇到任何文件锁定问题.但是请注意,这两种解决方案都依赖于本机的,依赖于操作系统的代码,因此我建议您在所有要使用的环境中进行测试. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |