我正在尝试读取gzip文件并将gzip文件的一部分(字符串)附加到另一个现有的gzip文件中。字符串的大小约为3000行。我将不得不在红宝石中多次(~10000次)这样做。这样做最有效的方法是什么? zlib库不支持追加和使用反引号(gzip -c orig_gzip >> gzip.gz
)似乎太慢了。生成的文件应该是一个巨大的文本文件
答案 0 :(得分:4)
目前尚不清楚您在寻找什么。如果您尝试将多个文件合并到一个gzip存档中,则无法实现。每the gzip documentation:
gzip可以将多个文件压缩到一个档案中吗?
不直接。您可以先创建一个tar文件然后压缩它: 对于GNU tar:
gtar cvzf file.tar.gz filenames
对于任何焦油: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
多次运行,你会看到输出增长。
这段代码是否足够快以满足您的需求很难说。这个例子人为地拖了一下,每秒写一次。
答案 1 :(得分:2)
听起来你的附加数据足够长,只需将3000行压缩到gzip流并将其附加到现有的gzip流就足够了。 gzip具有以下属性:连接的两个有效gzip流也是有效的gzip流,并且该gzip流解压缩为两个原始gzip流的解压缩的串联。
我不明白" (gzip -c orig_gzip >> gzip.gz)
似乎太慢"。那将是最快的方式。如果您不喜欢压缩所花费的时间,可以降低压缩级别,例如: gzip -1
。
当使用低级函数时,zlib库实际上支持了很多。您可以在examples/
directory的zlib distribution中看到附加gzip的高级示例。您可以通过首先解压缩现有的gzip流并获取上一个流停止的压缩来查看gzappend.c
,它在压缩方面比简单连接更有效。 gzlog.h
和gzlog.c
提供了一种将短消息附加到gzip流的有效且强大的方法。
答案 2 :(得分:0)
您需要以二进制模式(b
)和附加模式(a
)打开压缩文件,在我的情况下,它是CSV压缩文件。
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