Java Globbing模式匹配目录和文件

时间:2014-08-11 17:51:58

标签: java scala glob

我正在使用递归函数遍历根目录下的文件。我只想提取*.txt个文件,但我不想排除目录。现在我的代码看起来像这样:

val stream = Files.newDirectoryStream(head, "*.txt")

但是通过这样做,它将不匹配任何目录,并且iterator()返回的是False。我正在使用Mac,因此我不想包含的噪音文件是.DS_STORE。如何让newDirectoryStream获取*.txt的目录和文件?有办法吗?

3 个答案:

答案 0 :(得分:5)

你真的应该使用FileVisistor,它使代码变得如此简单:

import java.nio.file.attribute.BasicFileAttributes
import java.nio.file._

import scala.collection.mutable.ArrayBuffer

val files = ArrayBuffer.empty[Path]

val root = Paths.get("/path/to/your/directory")

Files.walkFileTree(root, new SimpleFileVisitor[Path] {
  override def visitFile(file: Path, attrs: BasicFileAttributes) = {
    if (file.getFileName.toString.endsWith(".txt")) {
      files += file
    }
    FileVisitResult.CONTINUE
  }
})

files.foreach(println)

答案 1 :(得分:1)

不确定是否需要nio。如果不是,这很简单,似乎可以完成这项工作。并且没有可变的集合:)

import java.io.File
def collectFiles(dir: File) = {
    def collectFilesHelper(dir: File, soFar: List[String]): List[String] = {
      dir.listFiles.foldLeft(soFar) { (acc: List[String], f: File) =>
        if (f.isDirectory)
          collectFilesHelper(f, acc)
        else if (f.getName().endsWith(".txt"))
          f.getCanonicalPath() :: acc
        else acc
      }
   }
   collectFilesHelper(dir, List[String]())
}

答案 2 :(得分:0)

好吧,我实际上并没有使用FileVisitor,但使用它应该很好。我使用了递归并保留了两个列表:一个是用于跟踪目录的原始文件列表,另一个列表用于存储实际的*.txt文件:

@tailrec
  def recursiveTraverse(filePaths: ListBuffer[Path], resultFiles: ListBuffer[Path]): ListBuffer[Path] = {

    if (filePaths.isEmpty) resultFiles
    else {
      val head = filePaths.head
      val tail = filePaths.tail

      if (Files.isDirectory(head)) {
        val stream: Try[DirectoryStream[Path]] = Try(Files.newDirectoryStream(head))
        stream match {
          case Success(st) =>
            val iterator = st.iterator()
            while (iterator.hasNext) {
              tail += iterator.next()   
            }
          case Failure(ex) => println(s"The file path is incorrect: ${ex.getMessage}")
        }
        stream.map(ds => ds.close())
        recursiveTraverse(tail, resultFiles)
      }
      else{
        if (head.toString.contains(".txt")) {
          recursiveTraverse(tail, resultFiles += head)
        }else{
          recursiveTraverse(tail, resultFiles)
        }
      }
    }
  }

但是,这不是最好的解决方案,但对我的具体问题来说是最简单的。如果你想这样做,请显示一个更短的FileVisitor代码:)