2016-07-28 4 views
1

start: Long - end: Long의 바이트 범위를 추출해야하는 바이너리 파일이 있습니다. 몇 기가 바이트가 있기 때문에 Long이 필요합니다. 내 앱은 결과를 ByteString으로 돌려줘야합니다. 내가 Scala의 파일에서 바이트 범위 추출

val content: Array[Byte] = Array() 
val stream: FileInputStream = new FileInputStream(file: File) 
stream.skip(start) 
stream.read(content, 0, end-start) 

을 시도했지만 이미 내가 readLong을 사용할 수 없습니다 만 Int (이 버그? skipLong으로 괜찮습니다 ...). 또한 결과를 ByteString으로 변환해야합니다. 나는 이것을 역시하고 싶다.

val stream: FileInputStream = new FileInputStream(file: File) 
stream.skip(start) 
org.apache.commons.io.IOUtils.toByteArray(stream) 

그러나 어디에서 끝낼 지 어떻게 말합니까? stream에는 방법이 없습니다 takeWhile 또는 take입니다. 그럼, 다시 나는 그렇게 할 수있는 방법 dropInt ...

val source = scala.io.Source.fromFile(file: File) 
source.drop(start).take(end-start) 

를 시도?

+0

http://stackoverflow.com/questions/28883876/can-i-do-a-lazy-take-with-a-long-parameter –

+0

대신, 당신은 뭔가를해야 Play에서 바이트 범위 요청에 대한 올바른 응답을 구현하려고 시도했지만 최근 Play에서이를 구현 한 것으로 보이며 "공용 자산 작업"에서 문서화했습니다 ... – JulienD

답변

0

사용 IOUtils.toByteArray(InputStream input, long size)

val stream = new FileInputStream(file) 
stream.skip(start) 
val bytesICareAbout = IOUtils.toByteArray(stream, end-start) 
// form the ByteString from bytesICareAbout 

end - startInteger.MAX_VALUE보다 큰 경우이 좋은 이유가 발생합니다! 2GB 어레이가 메모리에 할당되는 것을 원하지 않을 것입니다.

end - start > Integer.MAX_VALUE 어떤 이유로 든 데이터를 나타 내기 위해 하나의 ByteString을 할당하지 않아야합니다. I이었다두고

import org.apache.commons.io.input.BoundedInputStream 

val stream = new FileInputStream(file) 
stream.skip(start) 
val boundedStream = new BoundedInputStream(stream, start - end) 
+0

아, 두 번째가 있음을 알지 못했습니다. 생성자, 고마워, 작동 해! – JulienD