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 cat
die 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:
- Originaldatei
- HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
- Datei per Skript zusammengeführt
- HASH: c3e5a0404da480f36d37b65053732abe6d19034f60c3004a908b88d459db7d87
Datei manuell mit cat zusammengeführt
- HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
Befehl verwendet:
for i in /tmp/pycurl_*_{0..7}; do cat $i >> manually_merged.tar.gz; done
Teiledateien - am Ende von 0 bis 7 nummeriert
open
Modus ist nicht richtig (wb
). Basierend auf stackoverflow.com/a/4388244/3727050 benötigen Sieab
(oderr+b
undseek
)filename
,self.tempfile_arr
, undshutil
ist nicht definiertAntworten:
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 undcat
(die überhaupt keine Übersetzung machen würde) erklären .Versuchen Sie, Ihr Skript auszuführen, indem Sie
newline=''
(die leere Zeichenfolge) an übergebenopen
.quelle