2012-12-19 57 views
0

這是我正在嘗試的代碼。使用zlib壓縮Ruby中的完整目錄?

require 'zlib' 
Dir.glob('*.*').each do |file| 
    Zlib::GzipWriter.open('output.gz') do |gz| 
    gz.mtime = File.mtime(file) 
    gz.orig_name = File.basename(file) 
    gz.write IO.binread(file) 
    end 
end 

我試過不同的變化。網上似乎沒有「多個文件」的說明。我始終以ouput.gz中的第一個文件名結尾,我認爲它可能包含目錄中最後一個文件的內容(不確定)。但那不是重點。我只是想把每個文件作爲獨立的實體放在一個壓縮文件中。越平臺兼容越好。

+0

看到這個問題:http://stackoverflow.com/questions/2322921/using-rubyzip-to-add-files-and-nested-directories-to-a-zipoutputstream –

回答

-1

此答案取自http://old.thoughtsincomputation.com/posts/tar-and-a-few-feathers-in-ruby誰從RubyGems圖書館。

require 'rubygems' 
require 'rubygems/package' 
require 'zlib' 
require 'fileutils' 

module Util 
    module Tar 
    # Creates a tar file in memory recursively 
    # from the given path. 
    # 
    # Returns a StringIO whose underlying String 
    # is the contents of the tar file. 
    def tar(path) 
     tarfile = StringIO.new("") 
     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 
    end 

    # gzips the underlying string in the given StringIO, 
    # returning a new StringIO representing the 
    # compressed file. 
    def gzip(tarfile) 
     gz = StringIO.new("") 
     z = Zlib::GzipWriter.new(gz) 
     z.write tarfile.string 
     z.close # this is necessary! 

     # z was closed to write the gzip footer, so 
     # now we need a new StringIO 
     StringIO.new gz.string 
    end 

    # un-gzips the given IO, returning the 
    # decompressed version as a StringIO 
    def ungzip(tarfile) 
     z = Zlib::GzipReader.new(tarfile) 
     unzipped = StringIO.new(z.read) 
     z.close 
     unzipped 
    end 

    # untars the given IO into the specified 
    # directory 
    def untar(io, destination) 
     Gem::Package::TarReader.new io do |tar| 
     tar.each do |tarfile| 
      destination_file = File.join destination, tarfile.full_name 

      if tarfile.directory? 
      FileUtils.mkdir_p destination_file 
      else 
      destination_directory = File.dirname(destination_file) 
      FileUtils.mkdir_p destination_directory unless File.directory?(destination_directory) 
      File.open destination_file, "wb" do |f| 
       f.print tarfile.read 
      end 
      end 
     end 
     end 
    end 
    end 
end 


### Usage Example: ### 
# 
# include Util::Tar 
# 
# io = tar("./Desktop") # io is a TAR of files 
# gz = gzip(io)   # gz is a TGZ 
# 
# io = ungzip(gz)   # io is a TAR 
# untar(io, "./untarred") # files are untarred 
# 
2

首先,這將保持覆蓋output.gz,讓它只包含壓縮的最後一個文件。

其次,gzip格式不包含多個文件。它只有一個。您需要使用.tar.gz.zip格式。 .zip更「跨平臺兼容」。看看rubyzip