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

后端 未结 19 1440
旧巷少年郎
旧巷少年郎 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 04:04

    You can use tail recursion for it:

    object DirectoryTraversal {
      import java.io._
    
      def main(args: Array[String]) {
        val dir = new File("C:/Windows")
        val files = scan(dir)
    
        val out = new PrintWriter(new File("out.txt"))
    
        files foreach { file =>
          out.println(file)
        }
    
        out.flush()
        out.close()
      }
    
      def scan(file: File): List[File] = {
    
        @scala.annotation.tailrec
        def sc(acc: List[File], files: List[File]): List[File] = {
          files match {
            case Nil => acc
            case x :: xs => {
              x.isDirectory match {
                case false => sc(x :: acc, xs)
                case true => sc(acc, xs ::: x.listFiles.toList)
              }
            }
          }
        }
    
        sc(List(), List(file))
      }
    }
    
    0 讨论(0)
  • 2020-11-28 04:05

    And here's a mixture of the stream solution from @DuncanMcGregor with the filter from @Rick-777:

      def tree( root: File, descendCheck: File => Boolean = { _ => true } ): Stream[File] = {
        require(root != null)
        def directoryEntries(f: File) = for {
          direntries <- Option(f.list).toStream
          d <- direntries
        } yield new File(f, d)
        val shouldDescend = root.isDirectory && descendCheck(root)
        ( root.exists, shouldDescend ) match {
          case ( false, _) => Stream.Empty
          case ( true, true ) => root #:: ( directoryEntries(root) flatMap { tree( _, descendCheck ) } )
          case ( true, false) => Stream( root )
        }   
      }
    
      def treeIgnoringHiddenFilesAndDirectories( root: File ) = tree( root, { !_.isHidden } ) filter { !_.isHidden }
    

    This gives you a Stream[File] instead of a (potentially huge and very slow) List[File] while letting you decide which sorts of directories to recurse into with the descendCheck() function.

    0 讨论(0)
  • 2020-11-28 04:07

    Scala is a multi-paradigm language. A good "scala-esque" way of iterating a directory would be to reuse an existing code!

    I'd consider using commons-io a perfectly scala-esque way of iterating a directory. You can use some implicit conversions to make it easier. Like

    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))
    }
    
    0 讨论(0)
  • 2020-11-28 04:10

    No-one has mentioned yet 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")) 
    
    0 讨论(0)
  • 2020-11-28 04:11

    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

    But Java 1.8 introduces exactly what you are looking for:

    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.find and also java.nio.file.Files.newDirectoryStream

    See documentation here: http://docs.oracle.com/javase/tutorial/essential/io/walk.html

    0 讨论(0)
  • 2020-11-28 04:13

    How about

       def allFiles(path:File):List[File]=
       {    
           val parts=path.listFiles.toList.partition(_.isDirectory)
           parts._2 ::: parts._1.flatMap(allFiles)         
       }
    
    0 讨论(0)
提交回复
热议问题