我正在尝试读取一个 gzip 文件并将 gzip 文件的一部分(它是字符串)附加到另一个现有的 gzip 文件中。字符串的大小约为 3000 行。我将不得不在红宝石中多次(〜10000次)这样做。这样做最有效的方法是什么?zlib 库不支持追加和使用反引号 ( gzip -c orig_gzip >> gzip.gz
) 似乎太慢了。结果文件应该是一个巨大的文本文件
3 回答
目前尚不清楚您在寻找什么。如果您尝试将多个文件合并到一个 gzip 存档中,则无法到达那里。根据gzip 文档:
gzip 可以将多个文件压缩到一个存档中吗?
不是直接的。您可以先创建一个 tar 文件,然后将其压缩: 对于 GNU tar:
gtar cvzf file.tar.gz filenames
对于任何 tar:tar cvf - filenames | gzip > file.tar.gz
或者,您可以使用 zip、PowerArchiver 6.1、7-zip 或 Winzip。zip 格式允许随机访问存档中的任何文件,但 tar.gz 格式通常提供更好的压缩率。
随着您将添加到存档的次数,扩展源然后将字符串附加到单个文件,然后按需压缩或循环压缩更有意义。
您将有一个大文件,但压缩时间会很快。
如果您想在 gzip 文件中累积数据而不是单独的文件而不是全部展开,则可以从 Ruby 追加到现有的 gzip 文件,但是您必须"a"
在打开原始 .gzip 时指定(“追加”)模式文件。否则会导致您的原件被覆盖:
require 'zlib'
File.open('main.gz', 'a') do |main_gz_io|
Zlib::GzipWriter.wrap(main_gz_io) do |main_gz|
5.times do
print '.'
main_gz.puts Time.now.to_s
sleep 1
end
end
end
puts 'done'
puts 'viewing output:'
puts '---------------'
puts `gunzip -c main.gz`
其中,运行时,输出:
.....done
viewing output:
---------------
2013-04-10 12:06:34 -0700
2013-04-10 12:06:35 -0700
2013-04-10 12:06:36 -0700
2013-04-10 12:06:37 -0700
2013-04-10 12:06:38 -0700
运行几次,你会看到输出增长。
很难说这段代码是否足够快满足您的需求。这个例子人为地拖着脚每秒写一次。
听起来您附加的数据足够长,足以将 3000 行简单地压缩为 gzip 流并将其附加到现有的 gzip 流中。gzip 具有这样的属性,即两个有效的 gzip 流连接起来也是一个有效的 gzip 流,并且 gzip 流解压缩为两个原始 gzip 流的解压缩的连接。
我不明白“(gzip -c orig_gzip >> gzip.gz)
似乎太慢了”。那将是最快的方法。如果您不喜欢压缩所花费的时间,您可以降低压缩级别,例如gzip -1
.
当使用低级函数时,zlib 库实际上支持很多。您可以在zlib 发行版的examples/
目录中查看附加 gzip 的高级示例。您可以通过首先解压缩现有的 gzip 流并在前一个流停止的地方进行压缩 来查看,就压缩而言,它比简单的串联更有效地附加。并提供一种有效且健壮的方式将短消息附加到 gzip 流中。gzappend.c
gzlog.h
gzlog.c
您需要以二进制模式b
(a
file = File.open('path-to-file.csv.gz', 'ab')
gz = Zlib::GzipWriter.new(f)
gz.write("new,row,csv\n")
gz.close
如果您在w
模式下打开文件,您将覆盖文件的内容。检查文档以获取打开模式的完整描述http://ruby-doc.org/core-2.5.3/IO.html#method-c-new