我实现了一个使用Quartz在一段时间内读取文件夹的解决方案,对于每个文件,它执行一些操作并在文件完成时删除该文件。当我在目录中没有数千个文件时,这很顺利。
getFiles(config.getString("input")) match {
case Some(files) =>
files.foreach { file =>
try {
// check if file is in use
if (file.renameTo(file)) {
process(file, config)
}
} catch {
case e: Exception =>
} finally {
...
}
}
case None =>
...
}
def getFiles(path: String): Option[Array[File]] = {
new File(path).listFiles() match {
case files if files != null =>
Some(files.filter(file => file.lastModified < Calendar.getInstance.getTimeInMillis - 5000))
case _ =>
None
}
}
def process(file: File, clientConfig:Config) {
...
file.delete
}
现在我的情况不同了 - 我正在处理成千上万的文件 - 我的吞吐量非常慢:50 /秒(每个文件有40kb)。
我想知道处理许多文件的最佳方法是什么。我应该替换方法getFile()来返回N个元素并在每个元素上应用FileLock吗?如果我使用FileLock,我只能检索未使用的元素。或者我应该使用Java NIO的东西?
提前感谢。
答案 0 :(得分:0)
我认为您可以在Future
中包装try catch块,以便您可以并行处理文件。 Apparently using an Execution Context backed by a cached threadpool is best for IO bound operations.这也意味着您不必担心锁定,因为您同步为每个文件生成未来。
您还可以read the input files as a stream,这意味着您的代码将不再预先存储对所有内存中文件的引用,而只是存储对工作集的引用(一个文件),但我不认为这是你的瓶颈的原因。