从 GZIPInputStream 读取大量字节
Reading large number of bytes from GZIPInputStream
我正在通过 GZIPInputStream 读取 gzip 文件。我想一次读取大量数据,但无论我要求 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。为什么会这样?有没有办法解决这个问题,真的有更多的读取字节数?
如果您有大量数据,我会尝试使用 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()
好的,我找到了解决方案。 GZIPInputStream 的构造函数版本也采用缓冲区的大小。
读取的字节数可能总是 return 少于您要求的字节数,因此通常您总是必须循环读取,想读多少就读多少。
换句话说,给 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)
}
}
因此,loop to drain 而不是发出一读:
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使用,它只是为了演示。懒得写循环了
我正在通过 GZIPInputStream 读取 gzip 文件。我想一次读取大量数据,但无论我要求 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。为什么会这样?有没有办法解决这个问题,真的有更多的读取字节数?
如果您有大量数据,我会尝试使用 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()
好的,我找到了解决方案。 GZIPInputStream 的构造函数版本也采用缓冲区的大小。
读取的字节数可能总是 return 少于您要求的字节数,因此通常您总是必须循环读取,想读多少就读多少。
换句话说,给 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)
}
}
因此,loop to drain 而不是发出一读:
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使用,它只是为了演示。懒得写循环了