2016-07-28 56 views
1

我有一個二進制文件,我需要從start: Long - end: Long中提取一些字節範圍。我需要Long,因爲有幾個gigagbytes。我的應用程序需要將結果返回爲ByteString。我試圖從Scala文件中提取字節的範圍

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

,但我已經不能在read使用Long,只有Int(這是一個錯誤?skip是確定與Long ......)。此外,我需要將結果轉換爲ByteString。我也很想做到這一點:

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

但我該如何告訴它在哪裏結束? stream沒有方法takeWhiletake。然後我試圖

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

同樣,只有在dropInt ...

我怎麼能這樣做?

+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來表示數據。相反,你應該這樣做:

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

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

哦,我沒有看到有第二個構造函數,謝謝,它的工作原理! – JulienD