Ruby流tar/gz

Ton*_*y R 5 ruby gzip stream tar

基本上我想将内存中的数据流转换为tar/gz格式(可能是tar中的多个文件,但它永远不应该触及HARDDRIVE,只能流式传输!),然后将它们传输到其他地方(在我的情况下是HTTP请求体).

有人知道现有的库可以做到这一点吗?Rails中有什么东西吗?

libarchive-ruby只是一个C包装器,看起来它非常依赖于平台(文档希望你编译为安装步骤?!).

解:

require 'zlib'
require 'rubygems/package'

tar = StringIO.new

Gem::Package::TarWriter.new(tar) { |writer|
  writer.add_file("a_file.txt", 0644) { |f| 
    (1..1000).each { |i| 
      f.write("some text\n")
    }
  }
  writer.add_file("another_file.txt", 0644) { |f| 
    f.write("some more text\n")
  }
}
tar.seek(0)

gz = Zlib::GzipWriter.new(File.new('this_is_a_tar_gz.tar.gz', 'wb'))  # Make sure you use 'wb' for binary write!
gz.write(tar.read)
tar.close
gz.close
Run Code Online (Sandbox Code Playgroud)

而已!您可以将GzipWriter中的文件替换为任何IO以保持其流式传输.dw11wtq的饼干!

d11*_*wtq 6

看看在了RubyGems的TarWriter类:http://rubygems.rubyforge.org/rubygems-update/Gem/Package/TarWriter.html它只是上的IO流上进行操作,这可能是一个StringIO的.

tar = StringIO.new

Gem::Package::TarWriter.new(tar) do |writer|
  writer.add_file("hello_world.txt", 0644) { |f| f.write("Hello world!\n") }
end

tar.seek(0)

p tar.read #=> mostly padding, but a tar nonetheless
Run Code Online (Sandbox Code Playgroud)

如果您需要tarball中的目录布局,它还提供了添加目录的方法.

作为参考,您可以实现gzipping IO.popen,只需将数据输入/输出系统进程:

http://www.ruby-doc.org/core-1.9.2/IO.html#method-c-popen

gzip本身看起来像这样:

gzippped_data = IO.popen("gzip", "w+") do |gzip|
  gzip.puts "Hello world!"
  gzip.close_write
  gzip.read
end
# => "\u001F\x8B\b\u0000\xFD\u001D\xA2N\u0000\u0003\xF3H\xCD\xC9\xC9W(\xCF/\xCAIQ\xE4\u0002\u0000A?\r\u0000\u0000\u0000"
Run Code Online (Sandbox Code Playgroud)