[Scala] 스칼라 - 디렉토리의 파일에있는 모든 행에 대한 반복자


Answers

네, 비록 아주 간결하지는 않지만 :

import java.io.File
import scala.io.Source

for {
  file <- new File(dir).listFiles.toIterator if file.isFile
  line <- Source fromFile file getLines
} { doSomething line }

트릭은 flatMap 과 그것의 이해를 for 통사론 이다. 예를 들어 위의 내용은 다음과 다소 비슷합니다.

new File(dir)
  .listFiles.toIterator
  .filter(_.isFile)
  .flatMap(Source fromFile _ getLines)
  .map(doSomething)

Daniel Sobral이 아래 주석에 언급했듯이,이 접근법 (및 귀하의 질문에있는 코드)은 파일을 열어 놓을 것입니다. 이것이 일회성 스크립트이거나 REPL에서 일하는 중이라면 큰 문제가 아닐 수도 있습니다. 문제가 생기면 pimp-my-library 패턴 을 사용하여 기본적인 리소스 관리를 구현할 수 있습니다.

implicit def toClosingSource(source: Source) = new {
  val lines = source.getLines
  var stillOpen = true
  def getLinesAndClose = new Iterator[String] {
    def hasNext = stillOpen && lines.hasNext
    def next = {
      val line = lines.next
      if (!lines.hasNext) { source.close() ; stillOpen = false }
      line
    }
  }
}

이제 Source fromFile file getLinesAndClose 를 사용하면 열려있는 파일에 대해 걱정할 필요가 없습니다.

Question

나는 정말로

for (line <- Source fromFile inputPath getLines) {doSomething line}

스칼라에서 파일을 반복 처리하고 디렉토리의 모든 파일에서 행을 반복하는 데 유사한 구조를 사용하는 방법이 있는지 궁금해합니다.

중요한 제한 사항은 모든 파일이 힙 오버플로를 생성하는 공간을 더하는 것입니다. (GB의 수십 개를 생각하면 힙 크기를 늘리는 것은 선택 사항이 아닙니다.) 당분간 작업으로, 나는 하나의 파일로 모든 것을 묶어서 게으름의 b / c를 작동시키는 위의 구조를 사용하고 있습니다.

요점은, 이것과 같은 질문을 제기하는 것 같습니다 ... 내가 두 (100) 게으른 반복기를 연결하고 정말 큰, 게으른 하나를 얻을 수 있습니까?