java - 使用 Java 恢复失败的压缩

标签 java networking compression

我有少量 (2-10) 个较大的文件 (6-15GB),压缩效果非常好 (4:1)。

我正在用 Java 编写客户端和服务器,我想将文件从客户端发送到服务器,这样 1. 客户端在发送文件时压缩文件(即不创建中间 .zip 文件)
2. 服务器上的压缩文件最终会成为格式正确的文件(例如 .zip 或 .tgz 文件),以便可以“按原样”下载。
3. 中途失败可以恢复传输
4. resumed transfer 可能完全发生在一个新的进程中

前两个可以使用 java.io 套接字和 java.util.zip ZipOutputStreams 轻松实现。第三个是让我悲伤的那个。第四个实际上只是上下文。

我猜测解决方案可能需要某种部分重新传输或重新解析以建立字典或其他内容。

是否有任何支持可恢复压缩的 Java 库?

最佳答案

我找不到任何以我需要的方式支持可恢复压缩的预制库。然而,在开放许可下,有许多零碎的东西可以用来编写你自己的。我现在有一个客户端/服务器解决方案可以满足问题中列出的所有限制。

这个想法类似于上面概述的分块想法,但服务器管理分块并进行一些簿记,将客户端上的压缩 block 映射到服务器上的压缩 block 。解决方案中的任何地方都没有临时文件。基本协议(protocol)如下

(1) The client sends a manifest to the server, containing the
    to-be contents of the zip file  
(2) The server sends back an ID for the manifest  
    Then repeatedly  
  (3) The client asks the server "is there anything still 
      required for the manifest with ID X"
  (4) The server replies "no", or with a manifest entry 
      for a file in the manifest, plus a offset and length to send
  (5) The client compresses that chunk and sends it (plus some 
       bookkeeping info)
  (6) The server puts the chunk into the every growing zip file, 
      plus appropriate zip file crud. If the server orders 
      the chunks it asks the client for appropriately, this can 
      all be done by file appends.

服务器仅在每次第 6 步成功完成时更新 list ,因此可以安全地(或多或少)恢复第 3-6 步期间的失败(包括服务器或客户端崩溃)。

在按 block 创建 zip 文件时,有一些地方有点繁琐。需要实现的基本目标是找到一种可分块的压缩算法。 Deflate 可以以这种方式使用。

java ZipOutputStream 和 DeflaterOutputStream 并不真正适合“分块”压缩/压缩,因为它们不允许任意刷新。在 http://www.jcraft.com/jzlib 有一个 ZLib 的 BSD 风格许可的 java 实现。 .我没有对它进行速度基准测试,但它提供与 Java 实现相同的输出。 JZLib 很棒,支持 ZLib 的所有刷新模式(与 java.util.zip.Deflate 实现不同)。

此外,Zip 文件会为每个条目计算一个 CRC。因此,步骤 4 中的 list 条目包含一个“部分”CRC,它针对每个 block 进行更新并在步骤 5 中的簿记信息中发回。在 http://www.axlradius.com/freestuff/CRC32.java 有一个用于 java 的 CRC 的公共(public)域实现。 .我已经对它进行了基准测试,它与本地 Java 实现一样快(并提供等效的 CRC)。

最后,Zip 文件格式非常挑剔。我设法从维基百科页面和 http://www.pkware.com/documents/casestudies/APPNOTE.TXT 拼凑了大部分实现。 .尽管有一次我无法为其中一个字段计算出正确的值。幸运的是,JDK 的 ZipOutputStream 源代码可用,因此您可以看到它们的作用。

关于java - 使用 Java 恢复失败的压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3349749/

相关文章:

java - Java编译器创建新的局部变量或访问全局/成员变量的工作量是否减少了?

MySQL innodb COMPRESSED中KEY_BLOCK_SIZE取值注意事项

ssl - 使用 TLS 压缩的 Netty(不是 HTTP)?

java - hibernate @Formula/错误 : schema "FOO" does not exist

java - SQLException 您的 SQL 语法有错误

java - 从 ColdFusion 调用 .jar 并在客户端计算机上运行

java - 如何用 PHP、Python 或 Java 编写下载/上传速度监视器?

使用 C 语言的套接字 API 创建服务器和客户端程序,例如在线预订程序

c++ - 为网络消息设计类架构

css - Django 压缩器和部署