【问题标题】:Java Globbing Pattern to Match Directory and File用于匹配目录和文件的 Java Globbing 模式
【发布时间】:2014-10-04 15:27:50
【问题描述】:

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

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

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

【问题讨论】:

  • 使用FileVisitor 让它为你走树怎么样?
  • 您的意思是要递归地查看您为*.txt 找到的目录内部吗?我假设这一点,除非您期望目录名称也以 .txt 结尾。
  • @Hypino 是的,我正在尝试查找 *.txt 文件,但将其用作全局约束也会为我消除目录!
  • @biziclop 是的! FileVisitor 应该是要走的路!谢谢你。我应该删除这个帖子吗?它有点短。
  • @WindDweller 只需将您的解决方案添加为答案并接受它,以便其他有类似问题的人可以找到它。

标签: java scala glob


【解决方案1】:

你真的应该使用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)

【讨论】:

  • 我的递归代码实际上在服务器上中断了(我不知道发生了什么)。我会切换到FileVisitor :)
【解决方案2】:

不确定是否需要 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]())
}

【讨论】:

  • 蔚来是必须的!对不起:)
【解决方案3】:

好吧,我实际上并没有使用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 代码:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 2012-06-26
    • 2021-09-17
    • 1970-01-01
    • 2023-04-02
    • 2015-05-04
    • 2011-01-07
    相关资源
    最近更新 更多