我有一个程序可以不时地进入几个目录,并对这些目录中的文件进行某种处理。
问题是程序不时(每两三天)达到操作系统打开文件限制。
这是一个在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);
}
}
感谢。
答案 0 :(得分:0)
我遇到了同样的问题。在调用“解析”的情况下,打开了很多文件,我清楚地看到实现打开了一个输入流,但在失败的情况下可能不会关闭它。