Wie gehe ich mit mehreren Binärdateien in Python richtig um?

10

Ich arbeite derzeit an einem Multithread-Downloader mit Hilfe des PycURL-Moduls. Ich lade Teile der Dateien herunter und füge sie anschließend zusammen.

Die Teile werden getrennt von mehreren Threads heruntergeladen. Sie werden im Binärmodus in temporäre Dateien geschrieben. Wenn ich sie jedoch zu einer einzigen Datei zusammenführe (sie werden in der richtigen Reihenfolge zusammengeführt), stimmen die Prüfsummen nicht überein.

Dies geschieht nur unter Linux env. Das gleiche Skript funktioniert in Windows env einwandfrei.

Dies ist der Code (Teil des Skripts), der die Dateien zusammenführt:

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

Ich habe auch die write()Methode ausprobiert , aber sie führt zu demselben Problem, und für große Dateien wird viel Speicher benötigt.

Wenn ich catdie Teiledateien unter Linux manuell in eine einzelne Datei zusammenstelle und die Prüfsumme der Datei übereinstimmt, liegt das Problem beim Zusammenführen von Dateien durch Python.

EDIT:
Hier sind die Dateien und Prüfsummen (sha256), mit denen ich das Problem reproduziert habe:

Saumyakanta Sahoo
quelle
2
Ich denke dein openModus ist nicht richtig ( wb). Basierend auf stackoverflow.com/a/4388244/3727050 benötigen Sie ab(oder r+bund seek)
urban
3
Sie müssen ein minimal reproduzierbares Beispiel bereitstellen, einschließlich einiger Beispiel-Tempfiles. Ich denke, Sie sollten in der Lage sein, das Problem mit einigen Tempfiles von jeweils nur wenigen Bytes zu reproduzieren. Hoffentlich ist die Puffergröße nicht Teil des Problems. Auch der Binärmodus ist wahrscheinlich nicht wichtig, so dass Sie einfache Textdateien verwenden können.
wjandrea
FWIW Ich konnte das Problem mit zwei sehr kurzen Textdateien unter Linux leider nicht reproduzieren.
Wjandrea
Tatsächlich benötigt Pycurl einen Binärmodus, um Daten zu schreiben.
Saumyakanta Sahoo
3
OK, die Dateien Hilfe , aber der Code ist immer noch unvollständig: filename, self.tempfile_arr, und shutilist nicht definiert
wjandrea

Antworten:

0

Ein minimal reproduzierbarer Fall wäre praktisch, aber ich würde vermuten, dass universelle Zeilenumbrüche das Problem sind: Wenn Ihre Dateien Text im Windows-Stil (Zeilenumbrüche \r\n) sind, werden sie standardmäßig in Zeilenumbrüche im Unix-Stil ( \n) übersetzt lesen. Und dann werden diese Zeilenumbrüche im Unix-Stil in die Ausgabedatei zurückgeschrieben und nicht in die von Ihnen erwarteten Windows-Zeilen. Das würde die Divergenz zwischen Python und cat(die überhaupt keine Übersetzung machen würde) erklären .

Versuchen Sie, Ihr Skript auszuführen, indem Sie newline=''(die leere Zeichenfolge) an übergeben open.

Masklinn
quelle