gzip ファイルを読み取って、gzip ファイルの一部 (文字列) を別の既存の gzip ファイルに追加しようとしています。文字列のサイズは ~3000 行です。Rubyでこれを複数回(〜10000回)行う必要があります。これを行う最も効率的な方法は何ですか? zlib ライブラリは追加をサポートしておらず、バッククォート ( gzip -c orig_gzip >> gzip.gz
) の使用は遅すぎるようです。結果のファイルは巨大なテキスト ファイルになるはずです
3 に答える
あなたが探しているものは明らかではありません。複数のファイルを 1 つの gzip アーカイブに結合しようとすると、そこに到達できません。gzipのドキュメントによると:
gzip で複数のファイルを 1 つのアーカイブに圧縮できますか?
直接ではありません。最初に 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
それを数回実行すると、出力が大きくなることがわかります。
このコードがあなたのニーズに対して十分に速いかどうかはわかりません。この例では、人為的に足を引きずって 1 秒に 1 回書き込みます。
追加されたデータは、3000 行を単純に gzip ストリームに圧縮し、それを既存の gzip ストリームに追加するのに十分な長さであるように思えます。gzip には、連結された 2 つの有効な gzip ストリームも有効な gzip ストリームであるというプロパティがあり、その gzip ストリームは元の 2 つの gzip ストリームの解凍の連結に解凍されます。
(gzip -c orig_gzip >> gzip.gz)
「遅すぎるようです」がわかりません。それが最速の方法でしょう。圧縮にかかる時間が気に入らない場合は、圧縮レベルを下げることができますgzip -1
。
低レベル関数が使用される場合、zlib ライブラリは実際にかなりの量をサポートします。zlib ディストリビューションのexamples/
ディレクトリで、gzip の追加の高度な例を見ることができます。最初に既存の gzip ストリームを解凍し、前のストリームが中断したところから圧縮を取得することにより、単純な連結よりも圧縮に関してより効率的に追加 する を見ることができます。短いメッセージを gzip ストリームに追加するための効率的で堅牢な方法を提供します。gzappend.c
gzlog.h
gzlog.c