1

我正在尝试读取一个 gzip 文件并将 gzip 文件的一部分(它是字符串)附加到另一个现有的 gzip 文件中。字符串的大小约为 3000 行。我将不得不在红宝石中多次(〜10000次)这样做。这样做最有效的方法是什么?zlib 库不支持追加和使用反引号 ( gzip -c orig_gzip >> gzip.gz) 似乎太慢了。结果文件应该是一个巨大的文本文件

4

3 回答 3

4

目前尚不清楚您在寻找什么。如果您尝试将多个文件合并到一个 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

运行几次,你会看到输出增长。

很难说这段代码是否足够快满足您的需求。这个例子人为地拖着脚每秒写一次。

于 2013-04-10T00:56:25.273 回答
2

听起来您附加的数据足够长,足以将 3000 行简单地压缩为 gzip 流并将其附加到现有的 gzip 流中。gzip 具有这样的属性,即两个有效的 gzip 流连接起来也是一个有效的 gzip 流,并且 gzip 流解压缩为两个原始 gzip 流的解压缩的连接。

我不明白“(gzip -c orig_gzip >> gzip.gz)似乎太慢了”。那将是最快的方法。如果您不喜欢压缩所花费的时间,您可以降低压缩级别,例如gzip -1.

当使用低级函数时,zlib 库实际上支持很多。您可以在zlib 发行版的examples/目录中查看附加 gzip 的高级示例。您可以通过首先解压缩现有的 gzip 流并在前一个流停止的地方进行压缩 来查看,就压缩而言,它比简单的串联更有效地附加。并提供一种有效且健壮的方式将短消息附加到 gzip 流中。gzappend.cgzlog.hgzlog.c

于 2013-04-10T16:36:22.680 回答
0

您需要以二进制模式ba

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

于 2018-12-06T14:07:03.847 回答