2017-01-27 11 views
0

私はGZIPInputStreamでgzippedファイルを読んでいます。一度に大量のデータを読み込みたいのですが、GZIPInputStreamに読み込むバイト数にかかわらず、読み込むバイト数はずっと少なくなります。それは、この場合の81920であるbArrayの大きさにほぼ等しくなるべきである、例えば、GZIPInputStreamから多数のバイトを読み取る

val bArray = new Array[Byte](81920) 
val fis = new FileInputStream(new File(inputFileName)) 
val gis = new GZIPInputStream(fis) 
val bytesRead = gis.read(bArray) 

バイトの読み出しは、必ずどこかで1800バイトの周りにあります。なぜそれはこのようなものですか?この問題を解決する方法はありますか、本当に多くのバイト数を読み込んでいますか?

+0

あなたが読んでいるファイルの大きさはどれくらいですか? – raam86

+0

サンプルループ:https://github.com/scala/scala/blob/2.12.x/​​src/reflect/scala/reflect/io/Streamable.scala#L59 –

+0

@ som-snytt:サンプルにはgzipライブラリ。 – pythonic

答えて

0

OK、私は解決策を見つけました。 GZIPInputStream用のコンストラクタのバージョンがあり、これもバッファのサイズをとります。

2

大量のデータがある場合に備えて、akka-streamsを使用してみます。

implicit val system = ActorSystem() 
    implicit val ec = system.dispatcher 
    implicit val materializer = ActorMaterializer() 

    val fis = new FileInputStream(new File("")) 
    val gis = new GZIPInputStream(fis) 
    val bfs: BufferedSource = Source.fromInputStream(gis) 

bfsは、ストリーム処理のためのFlow APIを公開しています。

あなたはまた、そのからのストリームを取得することができます。

val ss: Stream[String] = bfs.bufferedReader().lines() 
1

読んでも返されるバイト数は、求めているバイト数よりも少なくなる可能性があります。一般に、常にループする必要があります。

つまり、GZIPInputStreamに大きいバッファを指定しても、指定された要求には埋め込まれません。だからではなく、loop to drain代わりつの読み出しを発行する

import java.util.zip.GZIPInputStream 
import java.io.FileInputStream 
import java.io.File 
import java.io.InputStream 
import java.io.FilterInputStream 

object Unzipped extends App { 
    val inputFileName = "/tmp/sss.gz" 
    val bArray = new Array[Byte](80 * 1024) 
    val fis = new FileInputStream(new File(inputFileName)) 
    val stingy = new StingyInputStream(fis) 
    val gis = new GZIPInputStream(stingy, 80 * 1024) 
    val bytesRead = gis.read(bArray, 0, bArray.length) 
    println(bytesRead) 
} 

class StingyInputStream(is: InputStream) extends FilterInputStream(is) { 
    override def read(b: Array[Byte], off: Int, len: Int) = { 
    val n = len.min(1024) 
    super.read(b, off, n) 
    } 
} 

import reflect.io.Streamable.Bytes 
    val sb = new Bytes { 
    override val length = 80 * 1024L 
    override val inputStream = gis 
    } 
    val res = sb.toByteArray() 
    println(res.length) // your explicit length 

は、私はそれだけでデモにだ、それが使用するAPIだとは言いませんよ。私はループを書くのが面倒です。

関連する問題