Jak poprawnie obsługiwać wiele plików binarnych w Pythonie?


10

Obecnie pracuję nad wielowątkowym downloaderem z pomocą modułu PycURL. Pobieram części plików i scalam je później.

Części są pobierane oddzielnie od wielu wątków, są zapisywane do plików tymczasowych w trybie binarnym, ale kiedy scalam je w jeden plik (są scalane w odpowiedniej kolejności), sumy kontrolne nie są zgodne.

Dzieje się tak tylko w Linux env. Ten sam skrypt działa bezbłędnie w środowisku Windows Env.

To jest kod (część skryptu), który łączy pliki:

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!')

Próbowałem również write()metody, ale powoduje to ten sam problem i zajmuje dużo pamięci dla dużych plików.

Jeśli ręcznie catpodłączyłem pliki części do jednego pliku w systemie Linux, suma kontrolna pliku się zgadza, problem polega na scaleniu plików przez Pythona.

EDYTOWAĆ:
Oto pliki i sumy kontrolne (sha256), których użyłem do odtworzenia problemu:


2
Myślę, że twój opentryb jest niewłaściwy ( wb). Na podstawie stackoverflow.com/a/4388244/3727050 potrzebujesz ab(lub r+bi seek)
— miejskich

3
Musisz podać minimalny odtwarzalny przykład, w tym niektóre przykładowe pliki tymczasowe. Myślę, że powinieneś być w stanie odtworzyć problem z kilkoma plikami tymczasowymi o wielkości zaledwie kilku bajtów. Mam nadzieję, że rozmiar bufora nie jest częścią problemu. Również tryb binarny prawdopodobnie nie jest ważny, więc możesz używać zwykłych plików tekstowych.
— wjandrea

FWIW Niestety nie byłem w stanie odtworzyć problemu z dwoma bardzo krótkimi plikami tekstowymi w systemie Linux.
— wjandrea

W rzeczywistości pycurl wymaga trybu binarnego do zapisywania danych.
— Saumyakanta Sahoo

3
OK, pomoc pliki ale kod jest nadal niekompletna: filename, self.tempfile_arr, i shutilsą niezdefiniowane
— wjandrea

Odpowiedzi:


0

Przypadek minimalnie powtarzalny byłby wygodny, ale podejrzewam że problemem są uniwersalne znaki nowej linii: domyślnie, jeśli twoje pliki są tekstem w stylu Windows (nowe linie są \r\n), zostaną one przetłumaczone na znaki nowej linii w Uniksie (\n ) czytanie. A potem te nowe wiersze w stylu uniksowym zostaną zapisane z powrotem do pliku wyjściowego, a nie w oczekiwanym stylu w stylu Windows. To by tłumaczyło rozbieżność między Pythonem acat pytonem (który nie zrobiłby żadnego tłumaczenia).

Spróbuj uruchomić skrypt przekazując newline=''(pusty ciąg) do open.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.