Atualmente, estou trabalhando em um downloader multiencadeado com a ajuda do módulo PycURL. Estou baixando partes dos arquivos e depois as mesclando.
As partes são baixadas separadamente de vários segmentos, elas são gravadas em arquivos temporários no modo binário, mas quando as mesclo em um único arquivo (elas são mescladas na ordem correta), as somas de verificação não coincidem.
Isso só acontece no Linux linux. O mesmo script funciona perfeitamente no ambiente Windows.
Este é o código (parte do script) que mescla os arquivos:
with open(filename,'wb') as outfile:
print('Merging temp files ...')
for tmpfile in self.tempfile_arr:
with open(tmpfile, 'rb') as infile:
shutil.copyfileobj(infile, outfile)
print('Done!')
Eu tentei o write()
método também, mas resulta com o mesmo problema e levará muita memória para arquivos grandes.
Se eu manualmente cat
os arquivos de peça em um único arquivo no linux, a soma de verificação do arquivo corresponde, o problema está na mesclagem de arquivos do python.
Edição:
Aqui estão os arquivos e somas de verificação (sha256) que eu usei para reproduzir o problema:
- Arquivo original
- HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
- arquivo mesclado por script
- HASH: c3e5a0404da480f36d37b65053732abe6d19034f60c3004a908b88d459db7d87
arquivo mesclado manualmente usando cat
- HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
Comando usado:
for i in /tmp/pycurl_*_{0..7}; do cat $i >> manually_merged.tar.gz; done
Arquivos de peça - numerados no final, de 0 a 7
open
modo não está certo (wb
). Baseado em stackoverflow.com/a/4388244/3727050 você precisaab
(our+b
eseek
)filename
,self.tempfile_arr
, eshutil
são indefinidosRespostas:
Um caso minimamente reproduzível seria conveniente, mas eu suspeitaria que as novas linhas universais sejam o problema: por padrão, se seus arquivos forem do tipo texto do Windows (novas linhas são
\r\n
), eles serão traduzidos para as novas linhas do estilo Unix (\n
) em lendo. E então essas novas linhas no estilo unix serão gravadas de volta no arquivo de saída, e não no estilo do Windows que você esperava. Isso explicaria a divergência entre python ecat
(que não faria nenhuma tradução).Tente executar seu script passando
newline=''
(a string vazia) paraopen
.fonte