scala 如何在scala中列出子目录中的所有文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2637643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I list all files in a subdirectory in scala?
提问by Nick Fortescue
Is there a good "scala-esque" (I guess I mean functional) way of recursively listing files in a directory? What about matching a particular pattern?
是否有一种很好的“scala-esque”(我想我的意思是功能性的)方式来递归列出目录中的文件?匹配特定模式怎么样?
For example recursively all files matching "a*.foo"in c:\temp.
例如递归的所有文件匹配"a*.foo"在c:\temp。
回答by Rex Kerr
Scala code typically uses Java classes for dealing with I/O, including reading directories. So you have to do something like:
Scala 代码通常使用 Java 类来处理 I/O,包括读取目录。因此,您必须执行以下操作:
import java.io.File
def recursiveListFiles(f: File): Array[File] = {
val these = f.listFiles
these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}
You could collect all the files and then filter using a regex:
您可以收集所有文件,然后使用正则表达式进行过滤:
myBigFileArray.filter(f => """.*\.html$""".r.findFirstIn(f.getName).isDefined)
Or you could incorporate the regex into the recursive search:
或者您可以将正则表达式合并到递归搜索中:
import scala.util.matching.Regex
def recursiveListFiles(f: File, r: Regex): Array[File] = {
val these = f.listFiles
val good = these.filter(f => r.findFirstIn(f.getName).isDefined)
good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_,r))
}
回答by yura
I would prefer solution with Streams because you can iterate over infinite file system(Streams are lazy evaluated collections)
我更喜欢使用 Streams 的解决方案,因为您可以遍历无限文件系统(Streams 是惰性评估集合)
import scala.collection.JavaConversions._
def getFileTree(f: File): Stream[File] =
f #:: (if (f.isDirectory) f.listFiles().toStream.flatMap(getFileTree)
else Stream.empty)
Example for searching
搜索示例
getFileTree(new File("c:\main_dir")).filter(_.getName.endsWith(".scala")).foreach(println)
回答by monzonj
As of Java 1.7 you all should be using java.nio. It offers close-to-native performance (java.io is very slow) and has some useful helpers
从 Java 1.7 开始,您都应该使用 java.nio。它提供了接近本机的性能(java.io 非常慢)并且有一些有用的助手
But Java 1.8 introduces exactly what you are looking for:
但是 Java 1.8 准确地介绍了您正在寻找的内容:
import java.nio.file.{FileSystems, Files}
import scala.collection.JavaConverters._
val dir = FileSystems.getDefault.getPath("/some/path/here")
Files.walk(dir).iterator().asScala.filter(Files.isRegularFile(_)).foreach(println)
You also asked for file matching. Try java.nio.file.Files.findand also java.nio.file.Files.newDirectoryStream
您还要求进行文件匹配。java.nio.file.Files.find也试试java.nio.file.Files.newDirectoryStream
See documentation here: http://docs.oracle.com/javase/tutorial/essential/io/walk.html
请参阅此处的文档:http: //docs.oracle.com/javase/tutorial/essential/io/walk.html
回答by Phil
for (file <- new File("c:\").listFiles) { processFile(file) }
回答by Duncan McGregor
I like yura's stream solution, but it (and the others) recurses into hidden directories. We can also simplify by making use of the fact that listFilesreturns null for a non-directory.
我喜欢 yura 的流解决方案,但它(和其他)会递归到隐藏目录中。我们还可以通过利用listFiles为非目录返回 null的事实来简化。
def tree(root: File, skipHidden: Boolean = false): Stream[File] =
if (!root.exists || (skipHidden && root.isHidden)) Stream.empty
else root #:: (
root.listFiles match {
case null => Stream.empty
case files => files.toStream.flatMap(tree(_, skipHidden))
})
Now we can list files
现在我们可以列出文件
tree(new File(".")).filter(f => f.isFile && f.getName.endsWith(".html")).foreach(println)
or realise the whole stream for later processing
或实现整个流以供后期处理
tree(new File("dir"), true).toArray
回答by ArtemGr
Scala is a multi-paradigm language. A good "scala-esque" way of iterating a directory would be to reuse an existing code!
Scala 是一种多范式语言。迭代目录的一个很好的“scala-esque”方式是重用现有代码!
I'd consider using commons-ioa perfectly scala-esque way of iterating a directory. You can use some implicit conversions to make it easier. Like
我会考虑使用 commons-io一种完美的 Scala-esque 迭代目录的方式。您可以使用一些隐式转换使其更容易。喜欢
import org.apache.commons.io.filefilter.IOFileFilter
implicit def newIOFileFilter (filter: File=>Boolean) = new IOFileFilter {
def accept (file: File) = filter (file)
def accept (dir: File, name: String) = filter (new java.io.File (dir, name))
}
回答by Renaud
回答by Phil
No-one has mentioned yet https://github.com/pathikrit/better-files
还没有人提到https://github.com/pathikrit/better-files
val dir = "src"/"test"
val matches: Iterator[File] = dir.glob("**/*.{java,scala}")
// above code is equivalent to:
dir.listRecursively.filter(f => f.extension ==
Some(".java") || f.extension == Some(".scala"))
回答by Dino Fancellu
How about
怎么样
def allFiles(path:File):List[File]=
{
val parts=path.listFiles.toList.partition(_.isDirectory)
parts._2 ::: parts._1.flatMap(allFiles)
}
回答by roterl
Scala has library 'scala.reflect.io' which considered experimental but does the work
Scala 有库“scala.reflect.io”,它被认为是实验性的,但可以完成工作
import scala.reflect.io.Path
Path(path) walkFilter { p =>
p.isDirectory || """a*.foo""".r.findFirstIn(p.name).isDefined
}

