我正试图找到最有效的方法来处理基于允许文件列表的多个文件夹中的文件。
我有一个允许我处理的文件列表。
流程如下
val allowedFiles = List("File1.json","File2.json","File3.json")
- 获取目录中的文件夹列表。为此我可以使用:
def getListOfSubDirectories(dir: File): List[String] =
dir.listFiles
.filter(_.isDirectory)
.map(_.getName)
.toList
- 从步骤2开始循环遍历每个文件夹。拿到所有的文件。为此,我将使用:
def getListOfFiles(dir: String):List[File] = {
val d = new File(dir)
if (d.exists && d.isDirectory) {
d.listFiles.filter(_.isFile).toList
} else {
List[File]()
}
}
- 如果文件从步骤3。在允许的文件列表中调用另一个方法来处理文件
所以我需要循环遍历第一个目录,获取文件,检查文件是否需要处理,然后调用另一个函数。我在考虑双循环,这是最有效的方法。我知道在scala中我应该使用递归函数,但是在调用额外方法的双重递归函数中失败了。
欢迎有任何想法
Files.find()
将同时进行深度搜索和过滤。
import java.nio.file.{Files,Paths,Path}
import scala.jdk.StreamConverters._
def getListOfFiles(dir: String, targets:Set[String]): List[Path] =
Files.find( Paths.get(dir)
, 999
, (p, _) => targets(p.getFileName.toString)
).toScala(List)
用法:
val lof = getListOfFiles("/DataDir", allowedFiles.toSet)
但是,根据需要的处理类型,您可以只处理遇到的每个文件,而不是返回List
。
import java.nio.file.{Files,Paths,Path}
def processFile(path: Path): Unit = ???
def processSelected(dir: String, targets:Set[String]): Unit =
Files.find( Paths.get(dir)
, 999
, (p, _) => targets(p.getFileName.toString)
).forEach(processFile)
您可以使用Files.walk
代码看起来像这样(我没有编译它,所以它可能有一些拼写错误)
import java.nio.file.{Files, Path}
import scala.jdk.StreamConverters._
def getFilesRecursive(initialFolder: Path, allowedFiles: Set[String]): List[Path] =
Files
.walk(initialFolder)
.filter(path => allowedFiles.contains(path.getFileName.toString.toLowerCase))
.toScala(List)
我不是Scala专家(我上次涉水大概是在18年前),但我认为一定有一种方法可以处理这段代码:
def getListOfSubDirectories(dir: File): List[String] =
dir.listFiles
.filter(_.isDirectory)
.map(_.getName)
.toList
并消除至少一个额外的列表创建。我发现这个问题很有启发性,然后在谷歌上搜索了withFilter
。
看起来你可以把上面的内容翻译成下面的内容。通过将filter
替换为withFilter
,不会创建一个新的列表,然后再进行迭代。
def getListOfSubDirectories(dir: File): List[String] =
dir.listFiles
.withFilter(_.isDirectory)
.map(_.getName)
.toList