zipfile เพื่อบีบอัดและคลายการบีบอัดไฟล์ ZIP ใน Python

ธุรกิจ

โมดูล zipfile ของไลบรารีมาตรฐาน Python สามารถใช้บีบอัดไฟล์เป็น ZIP และคลายการบีบอัดไฟล์ ZIP รวมอยู่ในไลบรารีมาตรฐาน ดังนั้นจึงไม่จำเป็นต้องติดตั้งเพิ่มเติม

เนื้อหาต่อไปนี้จะอธิบาย

  • บีบอัดไฟล์หลายไฟล์เป็นไฟล์ ZIP
  • เพิ่มไฟล์ใหม่ในไฟล์ ZIP ที่มีอยู่
  • บีบอัดไดเร็กทอรี (โฟลเดอร์) ลงในไฟล์ ZIP
  • บีบอัดเป็นไฟล์ ZIP ด้วยรหัสผ่าน
  • ตรวจสอบเนื้อหาของไฟล์ ZIP
  • แยก (แกะ) เนื้อหาทั้งหมดของไฟล์ ZIP
  • เลือกเนื้อหาของไฟล์ ZIP และแตกไฟล์

บีบอัดไฟล์หลายไฟล์เป็นไฟล์ ZIP

สร้างวัตถุ ZipFile และใช้เมธอด write() เพื่อเพิ่มไฟล์ที่คุณต้องการบีบอัด

ในการสร้างไฟล์ ZIP ใหม่ ให้ระบุพาธของไฟล์ ZIP ที่จะสร้างเป็นอาร์กิวเมนต์แรกของคอนสตรัคเตอร์ของออบเจกต์ ZipFile และอาร์กิวเมนต์ที่สองดังนี้w'

นอกจากนี้ วิธีการบีบอัดสามารถระบุเป็นอาร์กิวเมนต์ที่สามได้

  • zipfile.ZIP_STORED:เพียงรวมหลายไฟล์โดยไม่มีการบีบอัด (ค่าเริ่มต้น)
  • zipfile.ZIP_DEFLATED:การบีบอัด ZIP ปกติ (ต้องใช้โมดูล zlib)
  • zipfile.ZIP_BZIP2:การบีบอัด BZIP2 (ต้องใช้โมดูล bz2)
  • zipfile.ZIP_LZMA:การบีบอัด LZMA (ต้องใช้โมดูล lzma)

BZIP2 และ LZMA มีอัตราการบีบอัดที่สูงกว่า (สามารถบีบอัดให้มีขนาดเล็กลงได้) แต่เวลาที่ใช้ในการบีบอัดจะนานกว่า

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

วัตถุ ZipFile จะต้องปิดด้วยเมธอด close() แต่ถ้าคุณใช้คำสั่ง with คำสั่งจะปิดโดยอัตโนมัติเมื่อบล็อกเสร็จสิ้น

import zipfile

with zipfile.ZipFile('data/temp/new_comp.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt')
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

โดยการระบุอาร์กิวเมนต์ compress_type ของเมธอด write() จะสามารถเลือกวิธีการบีบอัดสำหรับแต่ละไฟล์ได้

with zipfile.ZipFile('data/temp/new_comp_single.zip', 'w') as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt', compress_type=zipfile.ZIP_DEFLATED)
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

เพิ่มไฟล์ใหม่ในไฟล์ ZIP ที่มีอยู่

ในการเพิ่มไฟล์ใหม่ให้กับไฟล์ zip ที่มีอยู่ ให้ตั้งค่าอาร์กิวเมนต์แรกของคอนสตรัคเตอร์เป็นพาธของไฟล์ zip ที่มีอยู่เมื่อสร้างออบเจ็กต์ ZipFile นอกจากนี้ ให้ตั้งค่าโหมดอาร์กิวเมนต์ที่สองดังนี้a'

ดังตัวอย่างข้างต้น เพียงเพิ่มไฟล์โดยใช้เมธอด write()

with zipfile.ZipFile('data/temp/new_comp.zip', 'a') as existing_zip:
    existing_zip.write('data/temp/test4.txt', arcname='test4.txt')

บีบอัดไดเร็กทอรี (โฟลเดอร์) ลงในไฟล์ ZIP

หากคุณต้องการบีบอัดไดเร็กทอรีทั้งหมด (โฟลเดอร์) ให้เป็นไฟล์ ZIP ไฟล์เดียว คุณสามารถใช้ os.scandir() หรือ os.listdir() เพื่อสร้างรายการไฟล์ได้ แต่จะใช้ make_archive() ในไฟล์ Shutil ได้ง่ายกว่า โมดูล.

ดูบทความต่อไปนี้

บีบอัดเป็นไฟล์ ZIP ด้วยรหัสผ่าน

โมดูล zipfile ไม่อนุญาตให้คุณสร้าง ZIP ที่ป้องกันด้วยรหัสผ่าน หากคุณต้องการบีบอัดไฟล์เป็นไฟล์ zip ที่ป้องกันด้วยรหัสผ่าน ให้ใช้ไลบรารี pyminizip ของบุคคลที่สาม

โปรดทราบว่าการบีบอัดไฟล์ ZIP ที่ป้องกันด้วยรหัสผ่านสามารถทำได้ด้วยโมดูล zipfile (ดูด้านล่าง)

ตรวจสอบเนื้อหาของไฟล์ ZIP

คุณสามารถตรวจสอบเนื้อหาของไฟล์ ZIP ที่มีอยู่ได้

สร้างวัตถุ ZipFile โดยการตั้งค่าไฟล์อาร์กิวเมนต์แรกในตัวสร้างเป็นเส้นทางของไฟล์ zip ที่มีอยู่และโหมดอาร์กิวเมนต์ที่สองเป็น ‘r’ อาร์กิวเมนต์ของโหมดสามารถละเว้นได้เนื่องจากค่าเริ่มต้นคือ ‘r’

คุณสามารถใช้เมธอด namelist() ของออบเจ็กต์ ZipFile เพื่อรับรายการไฟล์ที่เก็บถาวร

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    print(existing_zip.namelist())
# ['test1.txt', 'zipdir/test2.txt', 'zipdir/sub_dir/test3.txt', 'test4.txt']

แยก (แกะ) เนื้อหาทั้งหมดของไฟล์ ZIP

ในการแกะเนื้อหาของไฟล์ ZIP ให้สร้างวัตถุ ZipFile ที่มีไฟล์อาร์กิวเมนต์แรกในตัวสร้างเป็นเส้นทางไปยังไฟล์ ZIP ที่มีอยู่และโหมดอาร์กิวเมนต์ที่สองเป็น ‘r’ ดังในตัวอย่างด้านบน อาร์กิวเมนต์ของโหมดสามารถละเว้นได้เนื่องจากค่าเริ่มต้นเป็น ‘r’

เมธอด extractall() ของออบเจ็กต์ ZipFile จะแยก (คลายการบีบอัด) เนื้อหาทั้งหมดของไฟล์ ZIP อาร์กิวเมนต์แรก path ระบุพาธของไดเร็กทอรีที่จะแตกไฟล์ หากละเว้น ไฟล์จะถูกแตกไปยังไดเร็กทอรีปัจจุบัน

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extractall('data/temp/ext')

ไฟล์ ZIP ที่มีรหัสผ่านสามารถแตกได้โดยการระบุรหัสผ่านเป็นอาร์กิวเมนต์ pwd ของเมธอด extractall()

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extractall('data/temp/ext_pass', pwd='password')

เลือกเนื้อหาของไฟล์ ZIP และแตกไฟล์

หากคุณต้องการแตกไฟล์และแตกไฟล์บางไฟล์เท่านั้น ให้ใช้เมธอด extract()

อาร์กิวเมนต์แรกของเมธอด extract() คือชื่อของไฟล์ที่จะแตก และพาธอาร์กิวเมนต์ที่สองคือพาธของไดเร็กทอรีที่จะแตกไฟล์ หากละเว้นอาร์กิวเมนต์พาธ ไฟล์จะถูกแตกไปยังไดเร็กทอรีปัจจุบัน ชื่อของไฟล์ที่จะแตกไฟล์ควรมีพาธไปยังไดเร็กทอรีในไฟล์ ZIP หากถูกเก็บไว้ที่นั่น

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extract('test1.txt', 'data/temp/ext2')

เช่นเดียวกับวิธี extractall() วิธีการ extract() ยังอนุญาตให้คุณระบุรหัสผ่านเป็นอาร์กิวเมนต์ pwd

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extract('test1.txt', 'data/temp/ext_pass2', pwd='password')