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

后端 未结 19 1438
旧巷少年郎
旧巷少年郎 2020-11-28 03:35

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?

For example re

相关标签:
19条回答
  • 2020-11-28 03:55

    This incantation works for me:

      def findFiles(dir: File, criterion: (File) => Boolean): Seq[File] = {
        if (dir.isFile) Seq()
        else {
          val (files, dirs) = dir.listFiles.partition(_.isFile)
          files.filter(criterion) ++ dirs.toSeq.map(findFiles(_, criterion)).foldLeft(Seq[File]())(_ ++ _)
        }
      }
    
    0 讨论(0)
  • 2020-11-28 03:56

    I would prefer solution with Streams because you can iterate over infinite file system(Streams are lazy evaluated collections)

    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)
    
    0 讨论(0)
  • 2020-11-28 03:56
    for (file <- new File("c:\\").listFiles) { processFile(file) }
    

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

    0 讨论(0)
  • 2020-11-28 03:56

    It seems nobody mentions the scala-io library from scala-incubrator...

    import scalax.file.Path
    
    Path.fromString("c:\temp") ** "a*.foo"
    

    Or with implicit

    import scalax.file.ImplicitConversions.string2path
    
    "c:\temp" ** "a*.foo"
    

    Or if you want implicit explicitly...

    import scalax.file.Path
    import scalax.file.ImplicitConversions.string2path
    
    val dir: Path = "c:\temp"
    dir ** "a*.foo"
    

    Documentation is available here: http://jesseeichar.github.io/scala-io-doc/0.4.3/index.html#!/file/glob_based_path_sets

    0 讨论(0)
  • 2020-11-28 03:57

    Why are you using Java's File instead of Scala's AbstractFile?

    With Scala's AbstractFile, the iterator support allows writing a more concise version of James Moore's solution:

    import scala.reflect.io.AbstractFile  
    def tree(root: AbstractFile, descendCheck: AbstractFile => Boolean = {_=>true}): Stream[AbstractFile] =
      if (root == null || !root.exists) Stream.empty
      else
        (root.exists, root.isDirectory && descendCheck(root)) match {
          case (false, _) => Stream.empty
          case (true, true) => root #:: root.iterator.flatMap { tree(_, descendCheck) }.toStream
          case (true, false) => Stream(root)
        }
    
    0 讨论(0)
  • 2020-11-28 04:01

    Here's a similar solution to Rex Kerr's, but incorporating a file filter:

    import java.io.File
    def findFiles(fileFilter: (File) => Boolean = (f) => true)(f: File): List[File] = {
      val ss = f.list()
      val list = if (ss == null) {
        Nil
      } else {
        ss.toList.sorted
      }
      val visible = list.filter(_.charAt(0) != '.')
      val these = visible.map(new File(f, _))
      these.filter(fileFilter) ++ these.filter(_.isDirectory).flatMap(findFiles(fileFilter))
    }
    

    The method returns a List[File], which is slightly more convenient than Array[File]. It also ignores all directories that are hidden (ie. beginning with '.').

    It's partially applied using a file filter of your choosing, for example:

    val srcDir = new File( ... )
    val htmlFiles = findFiles( _.getName endsWith ".html" )( srcDir )
    
    0 讨论(0)
提交回复
热议问题