Não fique deprimido com isso ... tenho certeza que você conseguirá resolver esse problema!
Eu acho que o que está te atrapalhando com o tar é que "suporta pipes nomeados" significa que ele pode reconhecer os pipes nomeados e armazená-los como pipes nomeados dentro do arquivo, para que você possa restaurar mais tarde -los como pipes nomeados novamente ... O que não é realmente o que você quer.
Além disso, o formato dos arquivos tar não é muito adequado para o que você está fazendo, já que a entrada que descreve um arquivo é armazenada antes de seu conteúdo e a entrada do arquivo deve conter o tamanho do arquivo, a menos que você saiba o tamanho exato do arquivo. conteúdo com antecedência, é difícil fazer isso ...
Existe esta solução (veja TarFileStdin), que usa um hack para resolver o problema. Ele insere um TarInfo com tamanho de arquivo zero, depois armazena o conteúdo do arquivo e, finalmente, busca voltar ao offset do TarInfo original e o substitui pelo tamanho correto ... É um pouco hacky, mas deve funcionar ... Mas continue a ler.
Você mencionou "Eu quero poder indexar o tarball, para que eu possa extrair o arquivo de metadados rapidamente do arquivo .tar.xz", para que pareça mais um arquivo ZIP! O formato ZIP armazena o conteúdo de todos os arquivos primeiro e, em seguida, armazena uma tabela de informações de arquivos e compensações no final do CEP. Nesse sentido, é indexado, como você mencionou. A listagem do conteúdo do ZIP pode ser feita rapidamente, pois é fácil para as ferramentas encontrarem a tabela de arquivos começando do final do arquivo.
Você pode usar o formato de compactação nativo do ZIP ou usar o modo "armazenar" do ZIP (descompactado) e, em seguida, adicionar um arquivo xyz.pcap.xz dentro dele. Adicionar um arquivo * .xz ao ZIP teria a conveniência de usar um compressor externo, como um xz paralelo.
Os objetos zipfile.ZipFile
do Python 3 têm um open()
method que permite que você adicione um arquivo apenas por nome e receba um objeto de arquivo para o qual você pode escrever o conteúdo.
Você pode usar essa API e shutil.copyfileobj()
para adicionar seu pcap compactado de um canal nomeado ao arquivo ZIP:
import shutil
import zipfile
with zipfile.ZipFile('mydata.zip', 'w') as zf:
with zf.open('xyz.pcap.xz', 'w') as outputf:
with open('/path/to/namedpipe', 'r') as inputf:
shutil.copyfileobj(inputf, outputf)
zf.write('metadata.pickle') # from local directory
Este snippet de código supõe que você esteja gravando os dados pcap já comprimidos em xz no pipe nomeado e que você tenha os metadados já serializados em um arquivo chamado 'metadata.pickle' no diretório atual. (Claro, você poderia usar o open()
do ZipFile para serializar os metadados de pickles diretamente em uma entrada no arquivo ZIP também!)
Se você quiser usar a compactação nativa do zipfile, você pode definir uma compactação padrão para o ZipFile:
with zipfile.ZipFile('mydata.zip', 'w', zipfile.ZIP_LZMA) as zf:
(O padrão é ZIP_STORED, o que significa que não há compactação, que é provavelmente o que você deseja se você estiver enviando dados comprimidos xz).
Consulte a documentação do zipfile para obter mais detalhes. Novos Python's têm ainda mais recursos, por exemplo, com o Python 3.5 você pode realmente escrever o arquivo zip em um pipe para que você possa, por exemplo, enviá-lo diretamente para um host remoto através do SSH.
Espero que você ache isso útil! Se você realmente precisa de um tarball, tente esta resposta , mas eu realmente acho que a solução zipfile usando Python 3 é melhor abordagem para o caso de uso que você descreve! Então, se esse formato é uma possibilidade, eu realmente recomendo.