2016-07-28 16 views
1

Ich habe eine Binärdatei, die ich brauche, um einen Bereich von Bytes aus zu extrahieren: start: Long - end: Long. Ich brauche Long, weil es mehrere Gigagbytes gibt. Meine App muss das Ergebnis als ByteString zurückgeben. Ich habe versucht,Extrahieren Bereich von Bytes aus Datei in Scala

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

aber schon kann ich nicht Long in read verwenden, nur Int (ist das ein Fehler? skip ok ist mit Long ...). Außerdem müsste ich das Ergebnis in ByteString konvertieren. Ich würde auch gerne das tun:

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

aber wie kann ich sagen, wo zu Ende? stream hat keine Methode takeWhile oder take. Dann habe ich versucht

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

Wieder nur Int in drop ...

Wie kann ich das tun?

+0

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

+0

Damit war ich: Stattdessen sollten Sie so etwas wie tun versuchen, eine korrekte Antwort auf eine Byte-Range-Anfrage in Play zu implementieren, aber seit kurzem scheint Play das implementiert zu haben, und dokumentiert es in "Mit öffentlichen Ressourcen arbeiten" ... – JulienD

Antwort

0

Verwenden 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 

Hinweis dies aus, wenn end - start größer als Integer.MAX_VALUE ist, aus gutem Grund! Sie möchten nicht, dass ein 2-GB-Array im Arbeitsspeicher zugewiesen wird.

Wenn aus irgendeinem Grund Ihre end - start > Integer.MAX_VALUE, sollten Sie auf jeden Fall vermeiden, eine einzelne ByteString zuweisen, um die Daten darzustellen.

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

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

Oh, ich habe nicht gesehen, dass es eine Sekunde gab Konstruktor, danke, es funktioniert! – JulienD