В настоящее время я работаю над многопоточным загрузчиком с помощью модуля PycURL. Я загружаю части файлов и потом их объединяю.
Части скачиваются отдельно из нескольких потоков, записываются во временные файлы в бинарном режиме, но когда я их сливаю в один файл(сливаются в правильном порядке) контрольные суммы не совпадают.
Это происходит только в Linux env. Тот же скрипт безупречно работает в среде Windows.
Это код (часть скрипта), который объединяет файлы:
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!')
Я также пробовал метод write()
, но он приводит к той же проблеме, и для больших файлов требуется много памяти.
Если я вручную cat
файлы частей в один файл в linux, то контрольная сумма файла совпадает, проблема заключается в слиянии файлов python.
РЕДАКТИРОВАТЬ:
Вот файлы и контрольные суммы (sha256), которые я использовал для воспроизведения проблемы:
- Original file
- HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
- file merged by script
- HASH: c3e5a0404da480f36d37b65053732abe6d19034f60c3004a908b88d459db7d87
файл объединен вручную с помощью cat
- HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
Используемая команда:
for i in /tmp/pycurl_*_{0..7}; do cat $i >> manually_merged.tar.gz; done
Файлы частей — нумеруются в конце от 0 до 7.
open
не подходит (wb
). На основе stackoverflow.com/a/4388244/3727050 вам нужноab
(илиr+b
иseek
) - person urban   schedule 28.12.2019filename
,self.tempfile_arr
иshutil
не определены - person wjandrea   schedule 28.12.2019tempfile_arr
не в том порядке, в котором вы утверждаете, и т. д. - person chepner   schedule 13.01.2020write()
использует много памяти для больших файлов, хотя я пробовал использовать функциюwrite()
, у меня возникла та же проблема. - person Saumyakanta Sahoo   schedule 13.01.2020copyfileobj
, только он использует буфер фиксированного размера, чтобы избежать одновременного чтения всего исходного файла в память. Это просто цикл повторяющихсяx = src.read(SIZE); dst.write(x)
вызовов. - person chepner   schedule 13.01.2020