Як правильно обробляти кілька бінарних файлів у python?


10

Зараз я працюю над багатопотоковим завантажувачем за допомогою модуля PycURL. Я завантажую частини файлів і зливаю їх згодом.

Частини завантажуються окремо з декількох потоків, вони записуються у тимчасові файли у двійковому режимі, але коли я об'єдную їх у один файл (вони об’єднуються у правильному порядку), контрольні суми не відповідають.

Це відбувається тільки в Linux env. Цей же сценарій працює бездоганно у Windows env.

Це код (частина сценарію), який об'єднує файли:

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.

EDIT:
Ось файли та контрольні суми (sha256), які я використовував для відтворення проблеми:


2
Я думаю, що ваш openрежим неправильний ( wb). На основі stackoverflow.com/a/4388244/3727050 вам потрібно ab(або r+bі seek)
міський

3
Вам потрібно надати мінімально відтворюваний приклад, включаючи кілька прикладних темпфілів. Я думаю, ви повинні мати можливість відтворити проблему з декількома темпфілами по кілька байт кожен. Сподіваємось, розмір буфера не є частиною проблеми. Також двійковий режим, мабуть, не важливий, тому ви можете використовувати текстові файли.
wjandrea

FWIW На жаль, я не зміг відтворити проблему з двома дуже короткими текстовими файлами в Linux.
wjandrea

Насправді pycurl вимагає двійкового режиму для запису даних.
Saumyakanta Sahoo

3
OK, файли довідка , але ваш код по - , як і раніше неповна: filename, self.tempfile_arrі shutilне визначена
wjandrea

Відповіді:


0

Мінімально відтворюваний випадок був би зручним, але я б підозрював, що проблемою є універсальні нові рядки : за замовчуванням, якщо ваші файли є текстом у стилі Windows (нові рядки \r\n), вони перейдуть на переклад у нові рядки у стилі Unix ( \n) читання. І тоді нові рядки в стилі Unix будуть записуватися назад у вихідний файл, а не в стилі Windows, якого ви очікували. Це б пояснило розбіжність між python та cat(що б не робило жодного перекладу).

Спробуйте запустити свій сценарій newline=''(порожній рядок) до open.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.