一次一个将文件附加到 StringIO Tar 存档

Appending files to a StringIO Tar archive one at a time

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

我的最终目标是能够调用方法 add_file 将文件 add/append 存档,然后调用方法 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 存档中读取所有文件到变量,然后在每次添加新文件时重新添加所有文件。这是正确的行为吗?有解决办法吗?

谢谢

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

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