Java Globbing Pattern to Match Directory and File

假如想象 提交于 2019-12-07 18:50:34

问题


I'm using a recursive function to traverse files under a root directory. I only want to extract *.txt files, but I don't want to exclude directories. Right now my code looks like this:

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

But by doing this, it will not match any directories, and the iterator() gets returned is False. I'm using a Mac, so the noise file that I don't want to include is .DS_STORE. How can I let newDirectoryStream get directories and files that are *.txt? Is there a way?


回答1:


You really should use FileVisistor, it makes the code as simple as this:

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)



回答2:


Not sure if nio is a requirement. If not this is fairly simple and seems to do the job. And has no mutable collections :)

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



回答3:


Well, I didn't actually use FileVisitor, but it should be nice to use it. I used recursion and keep two lists: one is the raw file list to track down directories, the other list is used to store actual *.txt files:

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

However, this is not the best solution, but is the easiest for my specific problem. Please show a maybe much shorter FileVisitor code, if you want to do it :)



来源:https://stackoverflow.com/questions/25249424/java-globbing-pattern-to-match-directory-and-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!