É possível converter 7z para tar diretamente?

8

Eu tenho um arquivo .7z contendo ~ 360.000 imagens em vários diretórios. Eu gostaria de convertê-lo para um .tar para que eu possa abri-lo em outro computador. Existe uma maneira melhor do que extraí-lo para arquivos e compactá-los novamente? É possível fazer a conversão diretamente?

    
por Mohammad Moghimi 18.04.2015 / 11:58

2 respostas

8

Não é muito difícil escrever algo para fazer o trabalho. Aqui está um exemplo de script Perl (requer o módulo 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);

Se você quiser um arquivo tar.gz / tar.bz2 / tar.xz, adicione a linha archive_write_add_filter_gzip($out); ou archive_write_add_filter_bzip2($out); ou archive_tar_add_filter_xz($out); após a linha archive_write_set_format .

Isso não usa espaço em disco temporário (apenas o espaço para o arquivo tar de saída) e muito pouca RAM (apenas alguns MB para perl, mas funciona com os arquivos um bloco por vez, portanto, não é um problema se os arquivos são maiores que sua RAM).

    
por hobbs 19.04.2015 / 00:01
15

.7z archives são arquivos geralmente compactados com algum tipo de algoritmo, enquanto .tar archives são apenas arquivos.

Eles diferem em seu escopo e, na maioria dos casos, uma conversão exigiria uma descompactação opcional sempre seguida por uma extração do arquivo de origem. Mesmo que um arquivo .7z não usasse nenhuma compactação, ele ainda exigiria uma extração.

Dito isto, se você quisesse [descompactar] / extrair / rearchive o arquivo fonte de uma só vez, a resposta é que você não pode, pelo menos não usar as ferramentas padrão do Ubuntu porque tar não pode ler de stdin , então você não pode canalizar 7z e tar . De qualquer forma, é muito fácil automatizar tudo em um único comando:

mkdir tmp && 7z x <path_to_source_archive> -otmp && tar cf archive.tar tmp && rm -rf tmp

* < caminho_para_arquivo > = caminho para a origem .7z archive

Além disso, o tempo necessário para que os arquivos do arquivo fonte sejam gravados no disco e que os arquivos extraídos sejam lidos para [descompactar] / extrair / rearchive o arquivo fonte em duas etapas é um gargalo para a tarefa inteira < em> principalmente (embora não apenas) devido à baixa velocidade de E / S de um disco em potencial, portanto, uma solução parcial seria armazenar os arquivos temporários em um ramdisk para praticamente anular o gargalo geral:

  1. Crie o ponto de montagem para o sistema de arquivos do ramdisk: sudo mkdir /mnt/tmpfs
  2. Monte o sistema de arquivos do ramdisk: sudo mount -t tmpfs -o size=<tmpfs_size> tmpfs /mnt/ramdisk * < tmpfs_size > = tamanho do sistema de arquivos em bytes * 10 3 (1, 1K, 1M, 1G, ...)
  3. Executar 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 * < caminho_para_arquivo > = caminho para a origem .7z archive
  4. Desmonte o sistema de arquivos do ramdisk: sudo umount
  5. Remova o ponto de montagem do sistema de arquivos do ramdisk: sudo rmdir /mnt/tmpfs
por kos 18.04.2015 / 12:15

Tags