在Scala中查找与通配符String匹配的文件

时间:2014-12-18 10:16:41

标签: file scala wildcard scala-collections

如何获取与给定目录中的通配符匹配的所有文件的Array[io.BufferedSource]

即,如何定义方法io.Source.fromDir,以便

val txtFiles: Array[io.BufferedSource] = io.Source.fromDir("myDir/*.txt") // ???

FileUtils中注意到Apache Commons IO,但更为首选的是基于Scala API的方法,没有外部依赖关系。

4 个答案:

答案 0 :(得分:6)

scala> import reflect.io._, Path._
import reflect.io._
import Path._

scala> val r = """.*\.scala""".r
r: scala.util.matching.Regex = .*\.scala

scala> "/home/amarki/tmp".toDirectory.files map (_.name) flatMap { case n @ r() => Some(n) case _ => None }
res0: Iterator[String] = non-empty iterator

scala> .toList
res1: List[String] = List(bobsrandom.scala, ...)

或递归

scala> import PartialFunction.{ cond => when }
import PartialFunction.{cond=>when}

scala> "/home/amarki/tmp" walkFilter (p => p.isDirectory || when(p.name) {
     | case r() => true })
res3: Iterator[scala.reflect.io.Path] = non-empty iterator

答案 1 :(得分:2)

使用Java 8,可以遍历目录及其所有子目录。 然后将迭代器转换为scala,然后根据以.txt结尾的文件进行过滤:

import scala.collection.JavaConverters._ java.nio.file.Files.walk(Paths.get("mydir")).iterator().asScala.filter(file => file.toString.endsWith(".txt")).foreach(println)

答案 2 :(得分:1)

边缘有点粗糙,但可能是这样的:

def getFilesMatchingRegex(dir: String, regex: util.matching.Regex) = {
    new java.io.File(dir).listFiles
        .filter(file => regex.findFirstIn(file.getName).isDefined)
        .map   (file => io.Source.fromFile(file))
}

请注意,这不会获取子目录中的文件,也没有人们可能期望的更多高级通配功能(àlals ./**/*.scala)等等。

答案 3 :(得分:1)

以下是基于this great answer from @som-snytt的答案:

scala> import reflect.io._, Path._
import reflect.io._
import Path._

scala> "/temp".toDirectory.files.map(_.path).filter(name => name matches """.*\.xlsx""")
res2: Iterator[String] = non-empty iterator

作为数组:

scala> "/temp".toDirectory.files.map(_.path).filter(name => name matches """.*\.xlsx""").toArray
res3: Array[String] = Array(/temp/1.xlsx, /temp/2.xlsx, /temp/3.xlsx, /temp/a.1.xlsx, /temp/Book1.xlsx, /temp/new.xlsx)