วิธีจัดการไฟล์ไบนารีหลายไฟล์ในไพ ธ อนอย่างถูกต้อง?


10

ฉันกำลังทำงานกับตัวดาวน์โหลดแบบมัลติเธรดด้วยความช่วยเหลือของโมดูล PycURL ฉันกำลังดาวน์โหลดบางส่วนของไฟล์และรวมเข้าด้วยกันในภายหลัง

ชิ้นส่วนจะถูกดาวน์โหลดแยกต่างหากจากหลายเธรดซึ่งจะถูกเขียนไปยังไฟล์ชั่วคราวในโหมดไบนารี แต่เมื่อฉันรวมเข้าไปในไฟล์เดียว (รวมอยู่ในลำดับที่ถูกต้อง) checksums ไม่ตรงกัน

สิ่งนี้จะเกิดขึ้นใน 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 การตรวจสอบของไฟล์จะตรงกันปัญหาคือการรวมไฟล์ของงูใหญ่

แก้ไข:
นี่คือไฟล์และ checksums (sha256) ที่ฉันใช้ในการทำให้เกิดปัญหาซ้ำ:


2
ฉันคิดว่าopenโหมดของคุณไม่ถูกต้อง ( wb) ตามstackoverflow.com/a/4388244/3727050คุณต้องการab(หรือr+bและseek)
urban

3
คุณต้องให้ตัวอย่างที่ทำซ้ำได้น้อยที่สุดรวมถึงตัวอย่าง tempfiles ฉันคิดว่าคุณควรจะสร้างปัญหาขึ้นมาใหม่ด้วย tempfiles เพียงไม่กี่ไบต์ต่อครั้ง หวังว่าขนาดบัฟเฟอร์ไม่ได้เป็นส่วนหนึ่งของปัญหา นอกจากนี้โหมดไบนารีอาจไม่สำคัญดังนั้นคุณสามารถใช้ไฟล์ข้อความธรรมดาได้
wjandrea

FWIW ฉันไม่สามารถสร้างปัญหากับไฟล์ข้อความสั้น ๆ สองไฟล์บน Linux ได้อย่างน่าเสียดาย
wjandrea

pycurl จริง ๆ แล้วต้องการโหมดไบนารีเพื่อเขียนข้อมูล
Saumyakanta Sahoo

3
ตกลงไฟล์ความช่วยเหลือ แต่รหัสของคุณยังคงไม่สมบูรณ์: filename, self.tempfile_arrและshutilจะไม่ได้กำหนด
wjandrea

คำตอบ:


0

กรณีที่ทำซ้ำได้น้อยที่สุดจะสะดวก แต่ฉันสงสัยว่าบรรทัดใหม่สากลเป็นปัญหา: โดยค่าเริ่มต้นหากไฟล์ของคุณเป็นข้อความแบบ windows (มีการขึ้นบรรทัดใหม่\r\n) พวกเขาจะได้รับการแปลเป็นบรรทัดใหม่สไตล์ Unix ( \n) การอ่าน จากนั้นบรรทัดใหม่ของยูนิกซ์สไตล์นั้นจะถูกเขียนกลับไปที่ไฟล์เอาต์พุตแทนที่จะเป็นสไตล์ Windows ที่คุณคาดหวัง นั่นจะอธิบายความแตกต่างระหว่างไพ ธ อนและcat(ซึ่งไม่ต้องแปลอะไรเลย)

พยายามที่จะเรียกใช้ผ่านสคริปต์ของคุณnewline=''(สตริงว่างเปล่า) openไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.