何时使用 deflate() 的 deflateroutputstream?

问题描述

我正在尝试学习如何在寒假期间使用 deflateroutputstream 来消磨时间。我很困惑,因为当我查看文档 https://docs.oracle.com/javase/7/docs/api/java/util/zip/DeflaterOutputStream.html 时,它说 deflate() 用于将压缩数据写入输出流,而 write() 用于将数据写入 deflateroutputstream(压缩输出流)以进行压缩。

然而,我正在网上查看示例代码,但根本没有人使用 deflate()。到目前为止,我看到的所有代码都只是将 write() 写入 deflateroutputstream 而没有调用 deflate()。 https://stackoverflow.com/a/13060441/12181863
https://www.programcreek.com/java-api-examples/?api=java.util.zip.DeflaterOutputStream

Sample from geeksforgeeks

我注意到代码在 deflateroutputstream 中放置了一个文件输出流,但它是如何交互的?将数据写入 deflateoutputstream 时,是否会自动调用 deflate() 将压缩数据发送到 fileoutputstream?

解决方法

它是 protected:它旨在用于对该流进行子类化的任何内容,而您并未对其进行子类化,因此就您而言,这是一个无法包含在推理中的实现细节,并且不是不是让你调用的。

当然,除非您将其子类化。

你可以 - 它是一种用于在其上构建基于 LZ 的压缩流的工具包。这就是 GZipOutputStream 和 ZipOutputStream 对其进行扩展的原因:它们是不同的容器,或多或少使用相同的压缩技术。他们确实调用了deflate。除非您正在开发自己的基于 LZ 的压缩系统或为现有的非 zip、非 gz、非 deflater 压缩格式实现阅读器,否则这不适合您。

这些类型的输出流被称为“过滤流”:它们本身不代表任何资源,它们环绕一个。它们可以环绕任何 OutputStream(或任何 InputStream,可以说这个概念适用于“双方”),并修改传输中的字节。

var out = new DeflaterOutputStream(whatever) 创建一个新的 deflater 流,它将压缩您发送给它的任何数据(通过 out.write(stuff)),然后它会依次获取压缩数据并将其发送到任何地方。它的作用是:

  1. 获取字节(按照 out.write),缓冲完成工作所需的数量:
  2. ...压缩这些数据。
  3. 然后通过调用其 whatever 方法将压缩数据发送到包装的输出流(在此示例中为 write)来处理压缩数据。

基本用法是:

  1. 创建资源,例如 Files.newOutputStreamsomeSocket.getOutputStreamhttpServletResponse.getOutputStream()System.out 或任何其他产生流的东西 - 这是一个抽象概念,其原因是:使事情灵活。
  2. 将该资源包装成一个 DeflaterOutputStream
  3. 将所有数据写入 deflateroutputstream。忘记原来的 - 你制作它是为了你可以将它传递给 DeflaterOutputStream,这就是你与底层流的交互结束的地方。
  4. 关闭 deflaterstream(最终也会关闭底层流)。