将文件一次添加到StringIO Tar存档

时间:2018-02-18 20:28:00

标签: ruby tar stringio

我正在编写使用StringIO对象和rubygems/package的代码,其中包含TarWriterTarReader

我的最终目标是能够调用方法add_file将文件添加/附加到存档,然后调用方法read_all_files以读回添加文件的文件名和内容

我目前的两种方法是:

require "rubygems/package"

def add_file(io)
  Gem::Package::TarWriter.new(io) do |tar|
    puts "What is the name of the file you wish to add?"
    print "> "
    filename = gets.chomp
    puts

    tar.add_file(filename, 0755) do |file|
      puts "Enter the file contents"
      print "> "
      contents = gets.chomp

      file.write contents
    end
  end
end

def read_all_files(io)
  Gem::Package::TarReader.new(io) do |tar|
    tar.each do |tarfile|
      puts "File Name> #{tarfile.full_name}"
      puts tarfile.read
    end
  end
end

#usage:

io = StringIO.new

add_file(io)
add_file(io)
add_file(io)
io.rewind
read_all_files(io)

输出:

What is the name of the file you wish to add?
> test1

Enter the file contents
> this is the first test
What is the name of the file you wish to add?
> test2

Enter the file contents
> this is the second test
What is the name of the file you wish to add?
> test3

Enter the file contents
> this is the third test
File Name> test1
this is the first test

目前正在发生的问题是,由于某种原因read_all_files只读取一个文件,尽管我应该迭代所有三个文件。

我尝试了各种想法,例如在每次add_file调用后重绕文件,但每次都会覆盖tar文件。我也试图寻找io对象的结尾并添加文件,但这也无法正常运行。

我最初认为TarWriter会读取标题并自动将新文件附加到tar档案中的正确位置,但似乎情况并非如此。

这似乎我需要将StringIO tar存档中的所有文件读取到变量,然后在每次添加新文件时重新添加所有文件。这是正确的行为吗?有办法解决这个问题吗?

由于

1 个答案:

答案 0 :(得分:0)

问题是因为每次调用add_file时都要创建一个新的TarWriter。您需要在对add_file的调用之间保留TarWriter对象。 e.g。

require "rubygems/package"

def add_file(io, tar=nil)

  tar = Gem::Package::TarWriter.new(io) if tar.nil?

  puts "What is the name of the file you wish to add?"
  print "> "
  filename = gets.chomp
  puts

  tar.add_file(filename, 0755) do |file|
    puts "Enter the file contents"
    print "> "
    contents = gets.chomp

    file.write contents
  end

  tar
end

def read_all_files(io)
  Gem::Package::TarReader.new(io) do |tar|
    puts 'TarReader created'
    tar.each do |tarfile|
      puts "File Name> #{tarfile.full_name}"
      puts tarfile.read
    end
  end
end

io = StringIO.new

tar1 = add_file(io)
tar1 = add_file(io, tar1)
tar1 = add_file(io, tar1)
io.rewind
read_all_files(io)

此输出:

   C:\Users\Administrator\test>ruby tarwriter.rb
   What is the name of the file you wish to add?
   > x.txt
   Enter the file contents
   > xxx
   What is the name of the file you wish to add?
   > z.txt
   Enter the file contents
   > zzz
   What is the name of the file you wish to add?
   > y.txt
   Enter the file contents
   > yyy
   TarReader created
   File Name> x.txt
   xxx
   File Name> z.txt
   zzz
   File Name> y.txt
   yyy