Java流 - 打开的文件太多了

时间:2017-03-28 13:09:56

标签: java java-stream

我有一个程序可以不时地进入几个目录,并对这些目录中的文件进行某种处理。

问题是程序不时(每两三天)达到操作系统打开文件限制。

这是一个在RHEL 7中运行的spring-boot应用程序。

获取文件的方法是:

public File[] getFiles(String dir, int numberOfFiles) throws Exception {
    final Path baseDir = Paths.get(dir);
    List<File> filesFromPath = new ArrayList<File>();
    File[] files = null;

    final BiPredicate<Path, BasicFileAttributes> predicate = (path, attrs) -> attrs.isRegularFile()
            && String.valueOf(path).endsWith(".xml");

    List<Path> result;

    try (Stream<Path> fileStream = Files.find(baseDir, 1, predicate).limit(numberOfFiles).onClose(() -> LOG.debug("Closing file stream."))){
        result = fileStream.collect(Collectors.toList());

        result.forEach(path -> {
            path.toString();
            File file = path.toFile();
            LOG.info("adding {} to process.", file.getName());
            filesFromPath.add(file);
        });

        if (filesFromPath != null && !filesFromPath.isEmpty()) {
            files = filesFromPath.toArray(new File[filesFromPath.size()]);
        }

    } catch (Exception e) {
        LOG.error("Error during file opening/closing", e);
    }

    if (files != null) {
        return files;
    }

    return new File[0];
}

我使用lsof命令查看我有多少打开的文件,目录列表总是在增长。

我在onClise方法中添加了一个日志,所有这些都是在打开流时调用的。

不应该尝试使用资源,关闭流吗?

[编辑]

还有另一个代码可以将已处理的文件移动到另一个文件夹。这段代码不使用流,除了丑陋之外,我无法发现它有什么问题。

public void move(File file, String archivePath) throws IOException {
    File backupFile = new File(archivePath);
    if (!backupFile.exists()) {
        backupFile.mkdirs();
    }

    Path source = file.toPath();
    if (file.exists()) {
        Path target = Paths.get(archivePath + File.separator + file.getName());
        Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
        LOG.info("file {} moved to {}", file, archivePath);
    } else {
        LOG.info("unable to move the file: {} because it was already moved to {}", file, archivePath);
    }
}

[编辑2]

正在处理所有文件:

private void processFile(File[] files) throws Exception {

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    XPath xpathParser = XPathFactory.newInstance().newXPath();

    for (int i = 0; i < files.length; i++) {

        File file = files[i];


        Document doc = db.parse(file);

        // DO STUFF
        fileUtils.move(file, processedPath);

    }

}

感谢。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。在调用“解析”的情况下,打开了很多文件,我清楚地看到实现打开了一个输入流,但在失败的情况下可能不会关闭它。

相关问题