[Java]Files.list等Stream方法导致打开文件数不释放(Too many open files)的解决方案

2021-01-11 213点热度 1人点赞 0条评论

最近发现一个问题,Tomcat运行一段时间后,就会发生崩溃现象,查找tomcat的logs/catalina.out日志,发现很多

java.io.IOException: Too many open files这样的错误日志

继续查找,ps au|grep java 找到tomcat的PID,lsof -p PID 看到具体的打开文件很多都是我最近添加的代码里Files.list(Paths.get(baseDir)).filter(...)这里的文件

可是Files.list这种Stream的方式浏览文件,最后不会自动关闭资源吗?经过确证,发现这种写法确实不会释放打开文件的资源,包括Files.walk() Files.find() Files.lines 等方法。

经过一番查找,问题顺利解决,换个方式,使用

try-with-resource

就会释放资源了,它可以自动调用资源的close方法。代码如下:

try (Stream<Path> stream = Files.list(baseDir)) {
    //or stream.filter等等都可以使用了
    stream.forEach(...);
}

try (Stream<Path> stream = Files.walk(baseDir, 5)) {
    //or stream.forEach等等都可以使用了
    stream.filter(...);
}

//File.find也同样使用try包起来,就可以了
try (Stream<Path> stream = Files.find(Paths.get(baseDir), 10, (filePath, fileAttr) -> {
    if (fileAttr.isRegularFile()) {
        String name = filePath.getFileName().toString();
        if (isContainsAllowedExts(name, allowedExts)) {
            return name.startsWith(keywords);
        }
    }
    return false;
    })) {
    foundFiles = stream.map(Path::toFile).sorted(Comparator.comparing(File::getName)).collect(Collectors.toList());
}

 

 

admin

这个人很懒,什么都没留下

文章评论

*

code