【问题标题】:Recursively walk a LARGE directory using Scala 2.8 continuations使用 Scala 2.8 continuations 递归遍历 LARGE 目录
【发布时间】:2012-04-07 07:17:11
【问题描述】:

是否可以使用 Scala 延续(在 2.8 中引入)递归遍历目录?

我的目录包含数百万个文件,所以我不能useStream,因为我会内存不足。我正在尝试编写 Actor dispatch 让工作人员并行处理文件。

有人有例子吗?

【问题讨论】:

  • 不是您问题的答案,但我很高兴在 Scala 中使用 Java 7's java.nio.file.FileVisitor 来处理包含数十万个文件的目录。它可能非常适合基于 Actor 的处理。
  • 看起来不错,但我想尝试并行处理至少几个文件。
  • 我在 FileVisitor 上遗漏了一些东西 - 它如何防止并行处理?由于每个文件都需要大量处理,因此将访问过的每个文件传递给 Actor。
  • @Ed Staub,对,我就是这么想的。
  • 你是对的。没想到。现在我脑子里有太多的信息流:-)。

标签: scala actor continuations directory-walk


【解决方案1】:

如果您想坚持使用 Java 1.6(而不是 1.7 中的 FileVistor),并且您有子目录而不是一个目录中的数百万个文件,您可以

class DirectoryIterator(f: File) extends Iterator[File] {
  private[this] val fs = Option(f.listFiles).getOrElse(Array[File]())
  private[this] var i = -1
  private[this] var recurse: DirectoryIterator = null
  def hasNext = {
    if (recurse != null && recurse.hasNext) true
    else (i+1 < fs.length)
  }
  def next = {
    if (recurse != null && recurse.hasNext) recurse.next
    else if (i+1 >= fs.length) {
      throw new java.util.NoSuchElementException("next on empty file iterator")
    }
    else {
      i += 1;
      if (fs(i).isDirectory) recurse = new DirectoryIterator(fs(i))
      fs(i)
    }
  }
}

这要求您的文件系统没有循环。如果它确实有循环,您需要跟踪您在一组中点击的目录并避免再次递归它们。 (如果您甚至不想在文件从两个不同的位置链接时两次点击文件,那么您必须将 everything 放入一个集合中,使用迭代器而不是只是将所有文件信息读入内存。)

【讨论】:

  • 呸。你必须比我的单行回复更详细,不是吗?而之前我也回答了!
【解决方案2】:

这是对问题的质疑,而不是答案。

如果您的进程受 I/O 限制,则并行处理可能不会大大提高您的吞吐量。在许多情况下,它会更糟,导致磁盘磁头抖动。在你沿着这条线做很多事情之前,看看磁盘有多忙。如果它大部分时间都在忙于一个线程,那么最多再增加一个线程将是有用的——即使这样也可能适得其反。

【讨论】:

  • 其实我对每个文件都做了很多处理,所以其他线程应该可以做一些有用的工作。
  • 我猜任何人在谈论存储在磁盘上的东西时使用“大”这个词可能是在谈论具有真实控制器的磁盘阵列,所以你不仅仅是在谈论一个物理上的磁头单元。但是,在进行软件更改之前查看实际 IO 行为的基本观点是正确的。
  • @Ed Staub:在这种情况下,文件位于 SSD 上。加载每个文件后,我需要对内容执行大量 CPU 密集型活动。考虑到我有许多超线程内核,并行处理似乎完全正确。
  • @Ralph - 我的意思是,如果当你的 IO 子系统饱和时,添加更多线程会受到伤害,而不是帮助。对于硬盘,过度搜索会加剧这种影响,但即使没有这种情况,上下文切换和降低的缓存局部性也会成为一个问题。 我并不是要说 IO 子系统不饱和的情况。如果你是计算密集型的,那就去吧。
【解决方案3】:

使用Iterator 怎么样?

【讨论】:

    猜你喜欢
    • 2019-06-24
    • 1970-01-01
    • 2013-06-01
    • 2016-04-30
    • 2018-11-15
    • 2023-01-09
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多