Bagaimana cara menangani beberapa file biner dengan python?

10

Saat ini saya sedang mengerjakan pengunduh multi-utas dengan bantuan modul PycURL. Saya mengunduh sebagian file dan menggabungkannya setelah itu.

Bagian-bagian diunduh secara terpisah dari beberapa utas, mereka ditulis ke file sementara dalam mode biner, tetapi ketika saya menggabungkannya menjadi file tunggal (mereka digabung dalam urutan yang benar), checksum tidak cocok.

Ini hanya terjadi di linux env. Skrip yang sama berfungsi dengan sempurna di Windows env.

Ini adalah kode (bagian dari skrip) yang menggabungkan file:

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

Saya mencoba write()metode juga, tetapi hasilnya dengan masalah yang sama, dan itu akan memakan banyak memori untuk file besar.

Jika saya secara manual catfile bagian menjadi satu file di linux, maka checksum file cocok, masalahnya adalah dengan penggabungan file python.

EDIT:
Berikut adalah file dan checksum (sha256) yang saya gunakan untuk mereproduksi masalah:

  • File asli
    • HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
  • file digabung dengan skrip
    • HASH: c3e5a0404da480f36d37b65053732abe6d19034f60c3004a908b88d459db7d87
  • file digabung secara manual menggunakan cat

    • HASH: 158575ed12e705a624c3134ffe3138987c64d6a7298c5a81794ccf6866efd488
    • Perintah yang digunakan:

      for i in /tmp/pycurl_*_{0..7}; do cat $i >> manually_merged.tar.gz; done
  • File bagian - diberi nomor pada bagian akhir, dari 0 hingga 7

Saumyakanta Sahoo
sumber
2
Saya pikir openmode Anda tidak benar ( wb). Berdasarkan stackoverflow.com/a/4388244/3727050 yang Anda butuhkan ab(atau r+bdan seek)
urban
3
Anda perlu memberikan contoh yang dapat direproduksi minimal termasuk beberapa contoh tempfile. Saya pikir Anda harus dapat mereproduksi masalah dengan beberapa tempfiles masing-masing hanya beberapa byte. Semoga ukuran buffer bukan bagian dari masalah. Mode biner juga mungkin tidak penting, jadi Anda bisa menggunakan file teks biasa.
wjandrea
FWIW Saya tidak dapat mereproduksi masalah dengan dua file teks yang sangat pendek di Linux sayangnya.
wjandrea
Sebenarnya pycurl memerlukan mode biner untuk menulis data.
Saumyakanta Sahoo
3
OK, file bantuan tapi kode Anda masih lengkap: filename, self.tempfile_arr, dan shutilyang terdefinisi
wjandrea

Jawaban:

0

Kasing yang dapat direproduksi minimal akan nyaman, tetapi saya menduga baris baru universal menjadi masalah: secara default, jika file Anda adalah teks bergaya windows (baris baru \r\n), mereka akan diterjemahkan ke baris baru gaya Unix ( \n) pada bacaan. Dan kemudian baris baru unix-style akan ditulis kembali ke file output daripada yang bergaya Windows yang Anda harapkan. Itu akan menjelaskan perbedaan antara python dan cat(yang tidak melakukan terjemahan apa pun).

Cobalah untuk menjalankan skrip Anda lewat newline=''(string kosong) ke open.

Masklinn
sumber