2

次のコードを再利用して tar ボールを作成しようとしています。

tarfile = File.open("#{Pathname.new(path).realpath.to_s}.tar","w")
      Gem::Package::TarWriter.new(tarfile) do |tar|
        Dir[File.join(path, "**/*")].each do |file|
          mode = File.stat(file).mode
          relative_file = file.sub /^#{Regexp::escape path}\/?/, ''
          if File.directory?(file)
            tar.mkdir relative_file, mode
          else
            tar.add_file relative_file, mode do |tf|
              File.open(file, "rb") { |f| tf.write f.read }
            end
          end
        end
      end
      tarfile.rewind
      tarfile

小さなフォルダーのみが含まれる限り問題なく動作しますが、大きなフォルダーは次のエラーで失敗します。

Error: Your application used more memory than the safety cap

メモリの問題を回避するためにチャンクで行うにはどうすればよいですか?

4

2 に答える 2

1

minitarはストリームに書き込むように見えるので、メモリは問題にならないと思います。メソッドのコメントと定義は次のpackとおりです (2013 年 5 月 21 日現在)。

# A convenience method to pack files specified by +src+ into +dest+. If
# +src+ is an Array, then each file detailed therein will be packed into
# the resulting Archive::Tar::Minitar::Output stream; if +recurse_dirs+
# is true, then directories will be recursed.
#  
# If +src+ is an Array, it will be treated as the argument to Find.find;
# all files matching will be packed.
def pack(src, dest, recurse_dirs = true, &block)
  Output.open(dest) do |outp|
    if src.kind_of?(Array)
      src.each do |entry|
        pack_file(entry, outp, &block)
        if dir?(entry) and recurse_dirs
          Dir["#{entry}/**/**"].each do |ee| 
            pack_file(ee, outp, &block)
          end                                                                                                                                                                                                                   
        end  
      end  
    else 
      Find.find(src) do |entry|
        pack_file(entry, outp, &block)
      end  
    end  
  end
end

tar を書くための README の例:

# Packs everything that matches Find.find('tests')
File.open('test.tar', 'wb') { |tar| Minitar.pack('tests', tar) }

gzip された tar を記述する README の例:

tgz = Zlib::GzipWriter.new(File.open('test.tgz', 'wb'))
  # Warning: tgz will be closed!
Minitar.pack('tests', tgz) 
于 2013-05-21T12:37:02.683 に答える