何时使用 deflateroutputstream 的 deflate()?

When to use deflate() of deflateroutputstream?

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

然而,我正在互联网上查看示例代码,但 none 完全使用 deflate()。到目前为止我看到的所有代码只是 write() 到 DeflaterOutputStream 而没有调用 deflate()
https://www.programcreek.com/java-api-examples/?api=java.util.zip.DeflaterOutputStream

我注意到代码在 DeflaterOutputStream 中放置了一个 FileOutputStream,但它是如何交互的? DeflaterOutputStream写入数据时是否自动调用deflate()将压缩后的数据发送到FileOutputStream?

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

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

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

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

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

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

基本用法是:

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