使用Scala 2.8 continuation递归遍历LARGE目录

时间:2012-03-22 17:14:46

标签: scala actor continuations directory-walk

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

我的目录包含数百万个文件,所以我不能use一个Stream,因为我会得到一个内存不足的内容。我正在尝试编写Actor dispatch来让工作者并行处理文件。

有没有人有例子?

3 个答案:

答案 0 :(得分:3)

如果你想坚持使用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)
    }
  }
}

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

答案 1 :(得分:1)

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

如果您的进程受I / O限制,并行处理可能无法提高您的吞吐量。在许多情况下,通过导致磁头颠簸,它会使更糟。在沿着这条线做很多事情之前,先看看磁盘有多忙。如果它在大多数情况下已经忙于单个线程,那么最多一个线程将是有用的 - 甚至可能适得其反。

答案 2 :(得分:0)

如何使用Iterator