디렉토리에있는 파일을 재귀 적으로 나열하는 좋은 “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에서 문서를 참조하십시오.
답변
답변
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