使用Java将数据附加到gzip文件

使用Java将数据附加到gzip文件,java,gzip,append,Java,Gzip,Append,我有一个可能很大(>4GB)的日志文件,所以我想“动态地压缩它”,这意味着我想直接在gzip文件的末尾插入文本(我想创建我自己的用于logback的文件追加器)。 是否可以将内容附加到现有的gzip文件中?看起来唯一的方法是用GZIPInputStream打开现有的GZIPInputStream,用GZIPOutputStream将数据读写到一个新文件中,并将新内容附加到新文件的末尾,然后我猜删除旧的gzip并将新文件重命名为旧名称 我错了吗?更好的主意 谢谢 虽然我不知道该问题的Java特定解

我有一个可能很大(>4GB)的日志文件,所以我想“动态地压缩它”,这意味着我想直接在gzip文件的末尾插入文本(我想创建我自己的用于logback的文件追加器)。 是否可以将内容附加到现有的gzip文件中?看起来唯一的方法是用GZIPInputStream打开现有的GZIPInputStream,用GZIPOutputStream将数据读写到一个新文件中,并将新内容附加到新文件的末尾,然后我猜删除旧的gzip并将新文件重命名为旧名称

我错了吗?更好的主意


谢谢

虽然我不知道该问题的Java特定解决方案,但有一些本机系统解决方案(假设您使用*nix,不关心它是否与平台无关)。Unix/Linux SE上的这个问题提供了一些解决方案(即压缩环回文件系统):


您可以查看zlib发行版中的示例,了解如何附加到gzip文件,以及如何为日志条目创建一个不断增长的gzip文件。您可以从、查看和获取zlib发行版。它们是用C编写的,可能需要zlib功能,而使用java.util.zip接口到zlib很难获得这些功能


这些方法不需要重新创建gzip文件。

gzip格式允许连接到以前的gzip字节流,允许在解压缩时显示为单个字符串


只需在末尾附加gzip数据

true
传递到
FileOutputStream
构造函数第二个参数以获取附加模式

File f = new File("out.gz");
OutputStream os = new GZIPOutputStream(new FileOutputStream(f, true)); // true for append
PrintWriter w = new PrintWriter(new OutputStreamWriter(os));
w.println("log message");
在我的示例数据中,此压缩比默认压缩级别
gzip
要好。(略好于7级,但不如8级)


对于短日志条目,这不是一个好方法。每个gzip文件都会增加18字节的开销,加上压缩短字符串(例如日志条目)通常是无效的。因此,您最好只使用普通日志文件。为了获得gzip压缩的好处,您需要使用我在回答中提到的示例中的技术将其保存在单个gzip流中。这很有效!我认为这应该是选择的答案。
$ ls -asl out.gz
88 -rw-r--r--  1 jem  staff  41859  5 Jul 07:42 out.gz
$ gunzip out.gz
$ gzip out
$ ls -asl out.gz
88 -rw-r--r--  1 jem  staff  42164  5 Jul 07:42 out.gz