我正在通过GZIPInputStream读取一个gzipped文件。我想一次读取大量数据,但是无论我要求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个字节左右,而它应该几乎等于bArray的大小,在本例中为81920。为什么是这样?有没有办法解决这个问题,并真正有更多的字节读取?
发布于 2017-01-27 21:02:44
好吧,我找到解决办法了。GZIPInputStream有一个构造函数的版本,它也具有缓冲区的大小。
发布于 2017-01-27 19:35:56
如果你有大量的数据,我会尝试使用akka流。
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()发布于 2017-01-29 00:38:55
read可能总是返回的字节比您所要求的要少,因此通常您必须循环,读取任意数量的字节。
换句话说,给GZIPInputStream一个大缓冲区并不意味着它会在给定的请求中被填充。
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,而是为了演示。我懒得写一个循环。
https://stackoverflow.com/questions/41900501
复制相似问题