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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:04:26  来源:igfitidea点击:

How do I list all files in a subdirectory in scala?

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) }

http://langref.org/scala+java/files

http://langref.org/scala+java/files

回答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

Apache Commons Io's FileUtilsfits on one line, and is quite readable:

Apache Commons Io 的FileUtils放在一行中,并且非常易读:

import scala.collection.JavaConversions._ // important for 'foreach'
import org.apache.commons.io.FileUtils

FileUtils.listFiles(new File("c:\temp"), Array("foo"), true).foreach{ f =>

}

回答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
}