2013-05-24 2 views
2

안녕하세요 저는 큰 데이터 수집 작업을 위해 가장 빠른 방법을 찾고 있습니다. 내 작업은 메모리에있는 큰 파일을 두 번 읽은 다음 몇 가지 통계 계산을 수행합니다 (이 작업의 데이터로 작업하는 가장 쉬운 방법은 무작위 액세스 배열입니다).스칼라 큰 파일 읽기

내 첫 번째 방법은 java.io.ByteArrayOutputStream을 사용하는 것이 었습니다. 내부 저장소의 크기를 조정할 수 있기 때문입니다.

def packTo(buf:java.io.ByteArrayOutputStream,f:File) = { 
    try { 
    val fs = new java.io.FileInputStream(f) 
    IOUtils.copy(fs,buf) 
    } catch { 
    case e:java.io.FileNotFoundException => 
    } 
} 

    val buf = new java.io.ByteArrayOutputStream() 
    files foreach { f:File => packTo(buf,f) } 
    println(buf.size()) 

    for(i <- 0 to buf.size()) { 
     for(j <- 0 to buf.size()) { 
      for(k <- 0 to buf.size()) { 
     // println("i " + i + " " + buf[i]); 
        // Calculate something amathing using buf[i] buf[j] buf[k] 
      } 
     } 
    } 

    println("amazing = " + ???) 

하지만 ByteArrayOutputStream 그것의 byte[] 전용 복사본으로 저를 얻을 수 없습니다. 그러나 나는 2 개의 데이터 사본을 가질 수 없다.

답변

6

scala-io을 사용해 보셨습니까? 그것으로 Resource.fromFile(f).byteArray처럼 간단해야합니다.

+0

입니다. scala-io는 매우 합리적인 해결책으로 보이지만 어떻게 효율적 concat 배열 [] 할 수 있습니다. 여기있을 수 있습니다 http://jesseeichar.github.io/scala-io-doc/0.4.2/index.html#!/core/add_all_bytes - 확실하지 않습니다 – Oleg

+0

Best Solution @ user500592 –

0

스칼라 라이브러리에 이미 그러나이

io.Source.fromFile("/file/path").mkString.getBytes 

을 할 수있는 좋은 API를 기본 제공, 종종 메모리에 바이트 배열로 전체 파일을로드하는 것은 좋은 생각이 아니다. 가능한 가장 큰 파일이 여전히 JVM 메모리에 제대로 맞는지 확인하십시오. 귀하의 답변은

+0

파일이 정말 큰 경우 OP가 말했듯이이 파일은 [OOM] (https://en.wikipedia.org/wiki/Out_of_memory) –

+1

을 생성합니다. 파일에 텍스트가 포함되어 있지 않으면'String '으로의 변환은 의미가없고 위험합니다. 어쨌든 파일의 원래 바이트를 얻기 위해'String'으로 변환하는 것은 너무 비싸고 원래의 바이트를 산출 할 수 없다. 마지막으로 인코딩을 지정하지 않고 byte-sequence ->'String' 또는'String' -> byte sequence 변환을 수행하는 것은 바람직하지 않습니다. –

+0

인코딩을 지정해야하며 암시 적입니다. 전체 메서드 시그니처는'def fromFile (name : String) (암시 적 코덱 : 코덱)'입니다. 네,'File' ->'String' ->'Array [Byte]'에서 변환하기위한 성능 오버 헤드가 있지만 대부분의 경우 (특히 스크립트를 작성할 때) 외부의 탐색과 해결에 더 많은 시간을 들일 필요가 없습니다 도서관 – Max