在 Ruby 中,如何将 tar 归档流直接提取到文件系统?

Posted

技术标签:

【中文标题】在 Ruby 中,如何将 tar 归档流直接提取到文件系统?【英文标题】:In Ruby, how can I extract a tar archive stream directly to the filesystem? 【发布时间】:2012-10-22 00:58:03 【问题描述】:

我正在使用 Grit (Ruby gem) 来加载一个 git repo,将给定的提交提取到一个文件夹,然后用它“做一些事情”。 Grit 支持带有archive_tar 的 git 存档,它返回一个“包含 tar 存档的字符串”。如果可能的话,我想使用 Ruby libs / gems 将它提取到文件系统(不是直接系统调用),并避免先将数据保存到存档然后提取它(真的在这里寻找一个有效的单行)。

【问题讨论】:

请出示您现在用来执行此操作的代码。 我之前真的没有代码来做这件事。我只是先用 Grit 制作了一个 tar 文件,然后将 tar 作为系统命令调用。 【参考方案1】:

假设'string contains tar archive'等价于

File.open("Downloads.tar", "rb") |a| a.read

我可以使用 fileutils、stringio 和 minitar gem 来完成这项工作。 首先你需要安装 minitar,应该很简单

gem install minitar

由于 minitar 不支持常规解包以使用流,我们将创建自己的基本解包方法。

require 'archive/tar/minitar'
require 'stringio'
require 'fileutils'

def unpack_tar(directory, string)
  FileUtils.mkdir_p(directory) if !File.exist?(directory)
  stringio = StringIO.new(string)
  input = Archive::Tar::Minitar::Input.new(stringio)
  input.each |entry|
    input.extract_entry(directory, entry)
  
end

unpack_tar("./test", File.open("Downloads.tar", "rb") |a| a.read )

当然,用 Grit gem 的 archive_tar 函数替换整个 File.open 部分。当然,这一切都是假设第一个假设,尽管我确信这个方法可以很容易地适应 archive_tar 实际返回的任何内容。

【讨论】:

这很好用,例如Grit::Repo.new('repo_dir').archive_tar('commit_id') 作为字符串。

以上是关于在 Ruby 中,如何将 tar 归档流直接提取到文件系统?的主要内容,如果未能解决你的问题,请参考以下文章

Linux提取RPM包文件(cpio命令)详解

Linux命令—tar

如何获取归档在 tar 中的文件(和其他属性)的创建时间?

39-tar 简明笔记

Linux tar 解压缩工具

Linux归档压缩文件(tar | gzip)