是否可以直接将 7z 转换为 tar?

Moh*_*imi 11 tar 7zip

我有一个 .7z 文件,在多个目录中包含 ~360,000 个图像。我想将其转换为 .tar,以便我可以在另一台计算机上打开它。有没有比将其提取到文件并再次压缩更好的方法?是否可以直接进行转换?

kos*_*kos 15

.7z档案是通常用某种算法压缩的档案,而.tar档案只是档案。

它们的范围不同,在大多数情况下,转换需要一个可选的解压缩,然后总是提取源存档。即使.7z存档不使用任何压缩,它仍然需要提取。

话虽如此,如果您打算立即[解压缩]/提取/重新存档源存档,答案是您不能,至少不能使用 Ubuntu 的默认工具,因为tar无法从中读取stdin,因此您不能通过管道7ztar. 无论如何,在单个命令中自动化所有内容非常容易:

mkdir tmp && 7z x <path_to_source_archive> -otmp && tar cf archive.tar tmp && rm -rf tmp
Run Code Online (Sandbox Code Playgroud)

* <path_to_archive> = 源.7z档案的路径

也被写入到磁盘,提取文件的源归档的文件所需的时间按顺序读取[解压缩] /提取/重新归档分两步源存档是整个任务的瓶颈主要是(altough不only) 由于潜在磁盘的 I/O 速度较低,因此部分解决方案是将临时文件存储到 ramdisk 以几乎消除整体瓶颈:

  1. 为 ramdisk 的文件系统创建挂载点: sudo mkdir /mnt/tmpfs
  2. 挂载 ramdisk 的文件系统:sudo mount -t tmpfs -o size=<tmpfs_size> tmpfs /mnt/ramdisk* <tmpfs_size> = 文件系统的大小(以字节为单位) * 10 3 (1, 1K, 1M, 1G, ...)
  3. 运行mkdir /mnt/tmpfs/tmp && 7z x <path_to_source_archive> -o/mnt/tmpfs/tmp && tar cf archive.tar /mnt/tmpfs/tmp && rm -rf /mnt/tmpfs/tmp* <path_to_archive> = 源.7z存档的路径
  4. 卸载 ramdisk 的文件系统: sudo umount
  5. 删除 ramdisk 文件系统的挂载点: sudo rmdir /mnt/tmpfs


hob*_*bbs 8

写一些东西来完成这项工作并不太难。这是一个示例 Perl 脚本(需要模块Archive::Libarchive::XS)。

#!/usr/bin/perl
use strict;
use warnings;
use Archive::Libarchive::XS qw(:all);

die "Usage: $0 in.7z out.tar" unless @ARGV == 2;
my ($infile, $outfile) = @ARGV;

my $in = archive_read_new();
archive_read_support_filter_none($in);
archive_read_support_format_7zip($in);

archive_read_open_filename($in, $infile, 10240) == ARCHIVE_OK
  or die "Error opening $infile: ", archive_error_string($in);

my $out = archive_write_new();
archive_write_set_format_ustar($out);
archive_write_open_filename($out, $outfile) == ARCHIVE_OK
  or die "Error opening $outfile: ", archive_error_string($out);

while (archive_read_next_header($in, my $entry) == ARCHIVE_OK) {
  archive_write_header($out, $entry) == ARCHIVE_OK
    or die archive_error_string($out);
  while (1) {
    my $size = archive_read_data($in, my $buff, 65536);
    die archive_error_string($in) if $size < 0; 
    last if $size == 0;
    archive_write_data($out, $buff) >= 0
      or die archive_error_string($out);
  }
} 

archive_read_free($in);
archive_write_close($out);
archive_write_free($out);
Run Code Online (Sandbox Code Playgroud)

如果你想要一个tar.gz / TAR.BZ2 / tar.xz存档,添加行archive_write_add_filter_gzip($out);archive_write_add_filter_bzip2($out);archive_tar_add_filter_xz($out);archive_write_set_format线。

这不使用临时磁盘空间(仅用于输出 tar 文件的空间)和很少的 RAM(对于 perl 仅几 MB,但它一次处理一个文件块,因此如果您的文件更大,这不是问题比你的内存)。