У меня есть файл .7z, содержащий ~ 360 000 изображений в нескольких каталогах. Я хотел бы преобразовать его в .tar, чтобы открыть его на другом компьютере. Есть ли лучший способ, чем распаковывать его в файлы и снова сжимать? Можно ли сделать преобразование напрямую?
Не слишком трудно записать что-то, чтобы сделать задание. Вот сценарий Perl в качестве примера (требует Архива модуля:: 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);
Если Вы хотели 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 (только некоторые МБ для жемчуга, но это работает с файлами блок за один раз, таким образом, это не проблема, если Ваши файлы больше, чем Ваша RAM).
.7z
архивы являются архивами, часто сжимаемыми с некоторым алгоритмом, в то время как .tar
архивы являются просто архивами.
Они отличаются по своему объему, и в большинстве случаев преобразование потребовало бы дополнительной распаковки, всегда сопровождаемой извлечением исходного архива. Даже если бы .7z
архив не использовал бы сжатия, он все еще потребовал бы извлечения.
Однако Если Вы означали [распаковывать] / извлечение / повторно архивирует исходный архив сразу, ответ - Вы, не может, по крайней мере, не используя инструменты Ubuntu по умолчанию, потому что tar
не может читать от stdin
, таким образом, Вы не можете передать по каналу 7z
и tar
. Так или иначе очень легко автоматизировать все в единственной команде:
mkdir tmp && 7z x <path_to_source_archive> -otmp && tar cf archive.tar tmp && rm -rf tmp
* < path_to_archive> = путь к источнику .7z
архив
Также время, необходимое, чтобы исходные файлы архива были записаны в диск и чтобы извлеченные файлы были считаны для [распаковывания] / извлечение/, повторно архивирует исходный архив на двух шагах, узкое место для целой задачи главным образом (хотя не только) из-за низкой скорости ввода-вывода потенциального диска, таким образом, частичное решение состояло бы в том, чтобы хранить временные файлы к электронному диску, чтобы почти освободить полное узкое место:
sudo mkdir /mnt/tmpfs
sudo mount -t tmpfs -o size=<tmpfs_size> tmpfs /mnt/ramdisk
* < tmpfs_size> = размер файловой системы в байтах * 10 <глоток> 3 глоток> (1, 1K, 1M, 1G...) 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
архив sudo umount
sudo rmdir /mnt/tmpfs