ep7 python : การแตกไฟล์ .zip ด้วยพี่เหลือม (extract .zip file by coding python)

Programming Aug 15, 2014

พอดีมีงานที่ต้องเขียนโค้ด โดยให้แตก .zip ออกมา โดยไม่ต้องให้ user ทำอะไรเลย แต่ user ไม่สามารถเห็นโค้ดเราได้ (และมีรายละเอียดอื่นอีก ไม่บอกแล้วกันเนอะ) เราคิดว่าพี่เหลือม ทำ .exe file ได้ เลยมาลองกับพี่เหลือมเลยคะ พี่เหลือมมี library ที่จัดการ .zip file ด้วย และมี library มากมายให้เลือกใช้

โจทย์ในประเด็นนี้คือ มี .zip อันนึง โครงสร้างภายในมี folder ชื่อเดียวกับไฟล์ แล้วค่อยเจอไส้ใน ดังนี้

ไส้ในควรมีมากกว่า 1 ไฟล์ เพื่อความชัวร์คะ

แล้วเราถามกู๋ ลองทำตามโค้ดในเว็บนึง ดังนี้

import os, zipfile

def unzip(path, zip):
  isdir = os.path.isdir
  join = os.path.join
  norm = os.path.normpath
  split = os.path.split

  for each in zip.namelist():
    if not each.endswith('/'):
    root, name = split(each)
    directory = norm(join(path, root))
    if not isdir(directory):
      os.makedirs(directory)
      file(join(directory, name), 'wb').write(zip.read(each))
if __name__ == '__main__':
  zip = zipfile.ZipFile('Python.zip', 'r')
  unzip('', zip)
  zip.close()

อธิบายเพิ่มเติม

  • zip.namelist() ดูว่าใน zip file ของเรานั้น ไส้ในมีไฟล์อะไรบ้าง
  • os.makedirs(directory) สร้าง directory มีอีกตัวคือ os.mkdir(directory, 0777)  ตัวเลขคือ mode ของเขา ใส่อะไรไปก็ได้ ค่ามาตรฐานของเขาคือ 0777
  • ตัว zip จะมีการเรียกไฟล์โดยใช้ zipfile.ZipFile('ชื่อไฟล์', 'โหมดการอ่าน') โดยมี file permission 3 ตัว คือ 'r' read, 'w' write และ 'a' execute โดยการยัดไฟล์เข้า zip ใช้คำสั่ง zip.write('ไฟล์ที่เราต้องการใส่') เมื่อเปิดแล้ว จะมีการปิด คือ zip.close()
  • ในตัวอย่าง มีการ split โดยใช้ library ของ os เป็นอีกวิธีนอกจากใช้ library ของ string ซึ่งจะมีตัวอย่างในโค้ดอันหลังคะ ให้ผลเหมือนกัน
  • join (os.path.join)เป็นการรวม 2 string เข้าด้วยกัน โดยมี "\\" คั่นระหว่าง 2 string นั้น เช่น

>>> join("test", "test33")

'test\\test33'

  • ส่วน norn (os.path.normpath) อันนี้เป็นการ link path directory ตามความเข้าใจของเรานะ

ในเว็บพี่เหลือมมีการอธิบาย library os ลองอ่านดูเพื่อความเข้าใจมากขึ้น

ปรากฏว่า extract ได้แค่ไฟล์แรกในนั้น โค้ดเหมือนจะถูกหมด เลยลองถูกลองผิดกันไป
เปลี่ยนโค้ดไปเรื่อยๆ พบว่า ติดปัญหาที่ folder ชื่อไฟล์ที่สร้างขึ้นเอง มีปัญหา Permission denied

เลยลองตรวจดูว่า  folder ชื่อไฟล์ที่เราสร้างนั้น มันมีอยู่หรือเปล่า ไม่มีก็ให้สร้าง จะได้ไม่มีปัญหา

สุดท้าย ออกเลย

ตอนนี้ก็ได้ตาม requirement เรียบร้อย ในขั้นแรก

ถ้าเราใส่ password แล้วต้องการให้ใช้โปรแกรมนี้ extract ออก ใช้คำสั่ง zip.setpassword(<password>) ก่อน for loop นะ

การทำงาน function คือ unzip(<path>, <zip_file>)
ถ้าอยากแตกไฟล์ที่อื่น ใส่ directory ที่ต้องการ ไว้ที่ <path>
ถ้าต้องการแตกไฟล์ที่เดียวกับ zip file ให้ใส่ '' ตามตัวอย่างเลยคะ :)

mikkipastel/pythonZipAttach
attach zip file with password by python version 3.3 - mikkipastel/pythonZipAttach

Tags

Minseo Chayabanjonglerd

I am a full-time Android Developer and part-time contributor with developer community and web3 world, who believe people have hard skills and soft skills to up-skill to da moon.