Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取太多打开的文件时出错,即使在使用了try with resources之后也是如此_Java_Ioexception - Fatal编程技术网

Java 获取太多打开的文件时出错,即使在使用了try with resources之后也是如此

Java 获取太多打开的文件时出错,即使在使用了try with resources之后也是如此,java,ioexception,Java,Ioexception,我们在tomcat 7上部署了一个应用程序,该应用程序生成csv文件,并在成功将其上传到目标系统后将其移动到存档文件夹 我已经编写了一个spring作业,用于清理早于阈值天数的文件 我们收到太多打开的文件错误,如下所示 java.nio.file.FileSystemException: /app/CSVArchive: Too many open files at sun.nio.fs.UnixException.translateToIOException(UnixException

我们在tomcat 7上部署了一个应用程序,该应用程序生成csv文件,并在成功将其上传到目标系统后将其移动到存档文件夹

我已经编写了一个spring作业,用于清理早于阈值天数的文件

我们收到太多打开的文件错误,如下所示

java.nio.file.FileSystemException: /app/CSVArchive: Too many open files
    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:91) ~[na:1.8.0_71]
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) ~[na:1.8.0_71]
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) ~[na:1.8.0_71]
    at sun.nio.fs.UnixFileSystemProvider.newDirectoryStream(UnixFileSystemProvider.java:427) ~[na:1.8.0_71]
    at java.nio.file.Files.newDirectoryStream(Files.java:457) ~[na:1.8.0_71]
    at java.nio.file.Files.list(Files.java:3451) ~[na:1.8.0_71]
    at com.kg.datahub.service.impl.CleanupServiceImpl.getFiles(CleanupServiceImpl.java:50) ~[kg-datahub-framework-1.0-SNAPSHOT.jar:na]
    at com.kg.datahub.job.FilesCleanupJob.execute(FilesCleanupJob.java:42) ~[kg-datahub-framework-1.0-SNAPSHOT.jar:na]
    at sun.reflect.GeneratedMethodAccessor414.invoke(Unknown Source) ~[na:na]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_71]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_71]
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) ~[spring-context-4.1.5.RELEASE.jar:4.1.5.RELEASE]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-4.1.5.RELEASE.jar:4.1.5.RELEASE]
下面是我的FileCleanupJob代码(使用了try with resources)

try(最终流olderArchiveFiles=cleanupService.getFiles(path.get(csvArchiveDirectory)、CSV\u FILE\u PATTHERN、thresholdDate)){
LOG.info(“删除存档文件…”);
cleanupService.deleteFiles(旧归档文件);
}
下面是清理服务代码

@Override
    public Stream<Path> getFiles(final Path locationPath, final String filePattern, final Date date) throws IOException {

            final Pattern pattern = Pattern.compile(filePattern);
            final DateFormat dateFormat = new SimpleDateFormat(datePattern);

            final Function<Path, String> captureDatePart = path -> {
                    final String fileName = path.getFileName().toString();
                    final Matcher matcher = pattern.matcher(fileName);
                    return matcher.find() ? matcher.group(1) : StringUtils.EMPTY;
            };

            final Function<String, Date> convertToDate = datePart -> {
                    try {
                            return dateFormat.parse(datePart);
                    } catch (ParseException e) {
                            throw Throwables.propagate(e);
                    }
            };

            final Function<Date, Boolean> checkIsOlder = fileDate -> fileDate.before(date);

            final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(globPattern);

            return Files.list(locationPath).filter(Files::isRegularFile).filter(pathMatcher::matches).filter(captureDatePart.andThen(convertToDate).andThen(checkIsOlder)::apply);

    }

   @Override
    public void deleteFiles(Stream<Path> files) {
            files.map(Path::toFile).forEach(File::delete);
    }
@覆盖
公共流getFiles(最终路径locationPath、最终字符串文件模式、最终日期)引发IOException{
最终模式=Pattern.compile(filePattern);
最终日期格式DateFormat=新的SimpleDateFormat(日期模式);
最终函数captureDatePart=路径->{
最终字符串文件名=path.getFileName().toString();
final Matcher Matcher=pattern.Matcher(文件名);
返回matcher.find()?matcher.group(1):StringUtils.EMPTY;
};
最终函数convertToDate=datePart->{
试一试{
returndateformat.parse(datePart);
}捕获(解析异常){
抛掷物。传播(e);
}
};
最终函数checkIsOlder=fileDate->fileDate.before(日期);
最终路径匹配器PathMatcher=FileSystems.getDefault().getPathMatcher(globPattern);
返回Files.list(locationPath).filter(Files::isRegularFile).filter(pathMatcher::matches).filter(captureDatePart.and then(convertToDate.and then(CheckIsOrder)::应用);
}
@凌驾
公共无效删除文件(流文件){
files.map(Path::toFile).forEach(File::delete);
}

有什么建议吗?

对我来说已经晚了,但我似乎记得我们在错误消息不完全正确的地方看到了类似的情况。问题是,IIRC,我们在TC应用程序中拥有的线程数量超过了ulimit,但这意味着一个开放文件问题。我们通过增加O/S级别的进程限制来解决这个问题。我可能记错了。你在用这些路径做什么?可能问题出在deleteFiles方法中(或其他打开文件但从不关闭文件的方法中)。@JBNizet Stream被传递到deleteFiles方法,我将在其中删除每个相应的文件。已更新问题以包含deleteFiles代码段。如日志所示,调用getFiles方法时发生异常。在本地系统和较低的环境中,我没有遇到这样的问题。假设您最多可以打开1000个文件描述符。如果在方法foo()和bar()中打开1000个,但忘记关闭它们,然后调用方法getFiles(),尝试打开第1001个。这就是抛出异常的地方,但问题出在foo()和bar()中,它们没有正确关闭文件。这是我的观点。不是说这是个问题,而是说它可能是个问题。
@Override
    public Stream<Path> getFiles(final Path locationPath, final String filePattern, final Date date) throws IOException {

            final Pattern pattern = Pattern.compile(filePattern);
            final DateFormat dateFormat = new SimpleDateFormat(datePattern);

            final Function<Path, String> captureDatePart = path -> {
                    final String fileName = path.getFileName().toString();
                    final Matcher matcher = pattern.matcher(fileName);
                    return matcher.find() ? matcher.group(1) : StringUtils.EMPTY;
            };

            final Function<String, Date> convertToDate = datePart -> {
                    try {
                            return dateFormat.parse(datePart);
                    } catch (ParseException e) {
                            throw Throwables.propagate(e);
                    }
            };

            final Function<Date, Boolean> checkIsOlder = fileDate -> fileDate.before(date);

            final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(globPattern);

            return Files.list(locationPath).filter(Files::isRegularFile).filter(pathMatcher::matches).filter(captureDatePart.andThen(convertToDate).andThen(checkIsOlder)::apply);

    }

   @Override
    public void deleteFiles(Stream<Path> files) {
            files.map(Path::toFile).forEach(File::delete);
    }