[scala] Scala의 하위 디렉토리에있는 모든 파일을 어떻게 나열합니까?

디렉토리에있는 파일을 재귀 적으로 나열하는 좋은 “scala-esque”(내가 기능성을 의미한다고 생각합니다) 방법이 있습니까? 특정 패턴을 일치시키는 것은 어떻습니까?

예를 들어 재귀 적으로 모든 파일이 일치 "a*.foo"에서 c:\temp.



답변

Scala 코드는 일반적으로 디렉토리 읽기를 포함하여 I / O를 처리하기 위해 Java 클래스를 사용합니다. 따라서 다음과 같이해야합니다.

import java.io.File
def recursiveListFiles(f: File): Array[File] = {
  val these = f.listFiles
  these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}

모든 파일을 수집 한 다음 정규식을 사용하여 필터링 할 수 있습니다.

myBigFileArray.filter(f => """.*\.html$""".r.findFirstIn(f.getName).isDefined)

또는 정규식을 재귀 검색에 통합 할 수 있습니다.

import scala.util.matching.Regex
def recursiveListFiles(f: File, r: Regex): Array[File] = {
  val these = f.listFiles
  val good = these.filter(f => r.findFirstIn(f.getName).isDefined)
  good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_,r))
}


답변

무한한 파일 시스템을 반복 할 수 있기 때문에 Streams 솔루션을 선호합니다 (스트림은 게으른 평가 컬렉션입니다)

import scala.collection.JavaConversions._

def getFileTree(f: File): Stream[File] =
        f #:: (if (f.isDirectory) f.listFiles().toStream.flatMap(getFileTree) 
               else Stream.empty)

검색 예

getFileTree(new File("c:\\main_dir")).filter(_.getName.endsWith(".scala")).foreach(println)


답변

Java 1.7부터는 모두 java.nio를 사용해야합니다. 네이티브에 가까운 성능을 제공하며 (java.io는 매우 느림) 유용한 도우미가 있습니다.

그러나 Java 1.8은 정확히 원하는 것을 소개합니다.

import java.nio.file.{FileSystems, Files}
import scala.collection.JavaConverters._
val dir = FileSystems.getDefault.getPath("/some/path/here") 

Files.walk(dir).iterator().asScala.filter(Files.isRegularFile(_)).foreach(println)

파일 일치도 요청했습니다. 시도 java.nio.file.Files.find하고 또한java.nio.file.Files.newDirectoryStream

http://docs.oracle.com/javase/tutorial/essential/io/walk.html에서 문서를 참조하십시오.


답변

for (file <- new File("c:\\").listFiles) { processFile(file) }

http://langref.org/scala+java/files


답변

Scala는 다중 패러다임 언어입니다. 디렉토리를 반복하는 좋은 “scala-esque”방법은 기존 코드를 재사용하는 것입니다!

commons-io를 사용하여 디렉토리를 반복하는 완벽하게 스칼라와 같은 방법을 고려할 것 입니다. 암시 적 변환을 사용하여 더 쉽게 만들 수 있습니다. 처럼

import org.apache.commons.io.filefilter.IOFileFilter
implicit def newIOFileFilter (filter: File=>Boolean) = new IOFileFilter {
  def accept (file: File) = filter (file)
  def accept (dir: File, name: String) = filter (new java.io.File (dir, name))
}


답변

나는 yura의 스트림 솔루션을 좋아하지만 숨겨진 디렉토리로 재귀합니다. listFiles디렉토리가 아닌 경우 null을 반환 한다는 사실을 활용하여 단순화 할 수도 있습니다 .

def tree(root: File, skipHidden: Boolean = false): Stream[File] = 
  if (!root.exists || (skipHidden && root.isHidden)) Stream.empty 
  else root #:: (
    root.listFiles match {
      case null => Stream.empty
      case files => files.toStream.flatMap(tree(_, skipHidden))
  })

이제 파일을 나열 할 수 있습니다.

tree(new File(".")).filter(f => f.isFile && f.getName.endsWith(".html")).foreach(println)

또는 나중에 처리하기 위해 전체 스트림을 실현

tree(new File("dir"), true).toArray


답변

Apache Commons Io의 FileUtils 는 한 줄에 맞으며 매우 읽기 쉽습니다 .

import scala.collection.JavaConversions._ // important for 'foreach'
import org.apache.commons.io.FileUtils

FileUtils.listFiles(new File("c:\temp"), Array("foo"), true).foreach{ f =>

}