如何在Scala中使用java.nio.file.Files.walkFileTree

Mar*_*tin 5 scala java-7

我想java.nio.file.Files.walkFileTree在Scala中使用new .我甚至成功了:

class Visitor
   extends
      java.nio.file.SimpleFileVisitor [java.nio.file.Path]
   {
   override def visitFile(
      File : java.nio.file.Path,
      Attrs : java.nio.file.attribute.BasicFileAttributes) : java.nio.file.FileVisitResult =
   {
      if (! File.toString.contains(".svn"))
      {
         System.out.println(File);
      } // if

      java.nio.file.FileVisitResult.CONTINUE;
   } // visitFile
} // Visitor

java.nio.file.Files.walkFileTree (Project_Home, new Visitor)
Run Code Online (Sandbox Code Playgroud)

但是,虽然这段代码工作得很好,但我觉得有点像将Java范例带入Scala.对真正的斯卡拉大师来说,这是一个问题:我有什么可以改进的,或者就是这样吗?

Dan*_*ral 6

访客真的是foreach没有功能的好处,所以让我们做一个foreach.该方法是静态的,但它作为第一个参数a Path,所以我们将丰富Path一个foreach方法,这是通过以下方式完成的:

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

implicit def fromNioPath(path: Path): TraverseFiles = new TraversePath(path)
Run Code Online (Sandbox Code Playgroud)

其他一切都在TraversePath课堂内,看起来有点像这样:

class TraversePath(path: Path) {
  def foreach(f: (Path, BasicFileAttributes) => Unit) {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

这足以让你写这个:

ProjectHome foreach ((file, _) => if (!file.toString.contains(".svn")) println(File))
Run Code Online (Sandbox Code Playgroud)

当然,它实际上不会做任何事情,所以让我们做点什么:

class TraversePath(path: Path) {
  def foreach(f: (Path, BasicFileAttributes) => Unit) {
    class Visitor extends SimpleFileVisitor[Path] {
      override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = try { 
        f(file, attrs)
        FileVisitResult.CONTINUE
      } catch { 
        case _ => FileVisitResult.TERMINATE
      }
    }
    Files.walkFileTree(path, new Visitor)
  }
}
Run Code Online (Sandbox Code Playgroud)

在那里,现在该行将与您的代码做同样的事情!但是,我们可以进一步改进它.碰巧这foreach是唯一需要的方法Traversable,所以我们可以扩展该类,并获得Scala集合的所有方法!

唯一的问题是一个Traversable.foreach函数只需要一个参数,而这里我们需要两个参数.但是,我们可以将其更改为接收元组.这是完整的代码:

import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
import scala.collection.Traversable

// Make it extend Traversable
class TraversePath(path: Path) extends Traversable[(Path, BasicFileAttributes)] {

  // Make foreach receive a function from Tuple2 to Unit
  def foreach(f: ((Path, BasicFileAttributes)) => Unit) {
    class Visitor extends SimpleFileVisitor[Path] {
      override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = try {
        // Pass a tuple to f
        f(file -> attrs)
        FileVisitResult.CONTINUE
      } catch { 
        case _ => FileVisitResult.TERMINATE
      }
    }
    Files.walkFileTree(path, new Visitor)
  }
}

ProjectHome foreach {
  // use case to seamlessly deconstruct the tuple
  case (file, _) => if (!file.toString.contains(".svn")) println(File)
}
Run Code Online (Sandbox Code Playgroud)

免责声明:我没有测试过这段代码,因为我没有安装Java 7.可能存在一些错误.