首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从GZIPInputStream读取大量字节

从GZIPInputStream读取大量字节
EN

Stack Overflow用户
提问于 2017-01-27 18:17:40
回答 3查看 1.4K关注 0票数 0

我正在通过GZIPInputStream读取一个gzipped文件。我想一次读取大量数据,但是无论我要求GZIPInputStream读取多少字节,它总是读取的字节数要少得多。例如,

代码语言:javascript
复制
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。为什么是这样?有没有办法解决这个问题,并真正有更多的字节读取?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-27 21:02:44

好吧,我找到解决办法了。GZIPInputStream有一个构造函数的版本,它也具有缓冲区的大小。

票数 0
EN

Stack Overflow用户

发布于 2017-01-27 19:35:56

如果你有大量的数据,我会尝试使用akka流。

代码语言:javascript
复制
  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。

您还可以从中获得一条流:

代码语言:javascript
复制
val ss: Stream[String] = bfs.bufferedReader().lines()
票数 2
EN

Stack Overflow用户

发布于 2017-01-29 00:38:55

read可能总是返回的字节比您所要求的要少,因此通常您必须循环,读取任意数量的字节。

换句话说,给GZIPInputStream一个大缓冲区并不意味着它会在给定的请求中被填充。

代码语言:javascript
复制
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)
  }
}

因此,相反,循环排水而不是发布一个读:

代码语言:javascript
复制
  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,而是为了演示。我懒得写一个循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41900501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档