Hướng dẫn unzip python - giải nén python

Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article) Dai Phong (you can also view the original English article)

Nếu bạn đã từng sử dụng máy tính, bạn có thể đã bắt gặp các tập tin với phần mở rộng .zip. Chúng là các tập tin đặc biệt có thể chứa nội dung được nén của nhiều tập tin, thư mục và thư mục con khác. Điều này giúp chúng được truyền tải trên trên internet một cách dễ dàng. Bạn có biết rằng bạn có thể sử dụng Python để nén hoặc giải nén tập tin?

Bài này sẽ hướng dẫn bạn cách làm thế nào để sử dụng mô-đun zipfile trong Python, để giải nén hoặc nén từng tập tin hay nhiều tập tin cùng một lúc.

Nén các Tập tin Riêng lẻ

Cái này thì dễ và đòi hỏi rất ít code. Chúng ta bắt đầu bằng cách import mô-đun zipfile và sau đó mở đối tượng ZipFile trong chế độ ghi bằng cách chỉ định tham số thứ hai là 'w'. Tham số đầu tiên là đường dẫn đến chính tập tin. Đây là code mà bạn cần:

import zipfile
      
jungle_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\jungle.zip', 'w')
jungle_zip.write('C:\\Stories\\Fantasy\\jungle.pdf', compress_type=zipfile.ZIP_DEFLATED)

jungle_zip.close()

Xin lưu ý rằng tôi sẽ chỉ định đường dẫn trong tất cả các đoạn code theo một định dạng kiểu Windows; bạn sẽ cần phải thay đổi phù hợp nếu bạn đang ở trên Linux hoặc Mac.

Bạn có thể chỉ định các phương thức nén khác nhau để nén các tập tin. Các phương thức mới hơn BZIP2LZMA được bổ sung trong Python phiên bản 3.3, và còn có một số công cụ khác mà không hỗ trợ hai phương thức nén này. Vì lý do này, yên tâm khi chỉ cần sử dụng phương thức DEFLATED. Bạn cũng nên thử những phương thức này để thấy sự khác biệt trong kích thước của các tập tin nén.

Nén nhiều Tập tin

Điều này hơi phức tạp một chút vì bạn cần lặp qua tất cả các tập tin. Code dưới đây sẽ nén tất cả các tập tin với phần mở rộng tập tin pdf trong một thư mục nhất định:

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()

Lần này, chúng ta đã import mô-đun

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
0 và sử dụng phương thức
import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
1 của nó để duyệt qua tất cả các tập tin và thư mục con trong thư mục gốc của chúng ta. Tôi chỉ nén các tập tin pdf trong thư mục. Bạn cũng có thể tạo các tập tin lưu trữ khác cho mỗi định dạng bằng cách sử dụng câu lệnh
import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
2.

Nếu bạn không muốn giữ lại cấu trúc thư mục, bạn có thể gom tất cả các tập tin với nhau bằng cách sử dụng dòng code sau:

fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)

Phương thức

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
3 chấp nhận ba tham số. Tham số đầu tiên là tên tập tin mà chúng ta muốn nén. Tham số thứ hai là không bắt buộc và cho phép bạn chỉ định một tên tập tin khác cho tập tin được nén. Nếu không được chỉ định, thì tên ban đầu được sử dụng.

Giải nén tất cả các Tập tin

Bạn có thể sử dụng phương thức

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
4 để giải nén tất cả các tập tin và thư mục từ một tập tin nén vào thư mục hiện tại. Bạn cũng có thể truyền một tên thư mục vào
import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
4 để giải nén các tập tin và thư mục trong một thư mục cụ thể. Nếu thư mục mà bạn truyền vào không tồn tại, phương thức này sẽ tạo nó cho bạn. Dưới đây là đoạn code bạn có thể sử dụng để giải nén các tập tin:

import zipfile
    	
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip')
fantasy_zip.extractall('C:\\Library\\Stories\\Fantasy')

fantasy_zip.close()

Nếu bạn muốn giải nén nhiều tập tin, bạn sẽ phải cung cấp tên của các tập tin mà bạn muốn giải nén dưới dạng một danh sách.

Giải nén từng Tập tin

Điều này cũng tương tự như giải nén nhiều tập tin. Một sự khác biệt là lần này, bạn cần phải cung cấp tên tập tin đầu tiên và đường dẫn để giải nén chúng vào đó. Ngoài ra, bạn cần phải sử dụng phương thức

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
6 thay vì
import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
4. Dưới đây là một đoạn code cơ bản để giải nén từng tập tin.

import zipfile
    	
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip')
fantasy_zip.extract('Fantasy Jungle.pdf', 'C:\\Stories\\Fantasy')

fantasy_zip.close()

Đọc các Tập tin Zip

Hãy xem xét một trường hợp mà bạn cần xem một tập tin lưu trữ zip có chứa một tập tin cụ thể nào đó hay không. Đến thời điểm này, lựa chọn duy nhất của bạn để làm điều đó là bằng cách giải nén tất cả các tập tin trong kho lưu trữ. Tương tự, bạn có thể cần phải giải nén chỉ những tập tin đó mà lớn hơn một kích thước cụ thể. Mô-đun

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
8 cho phép chúng ta kiểm tra nội dung của một tập tin nén mà không cần giải nén nó.

Sử dụng phương thức

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
9 của đối tượng ZipFile sẽ trả về một danh sách tất cả các thành phần của một tập tin nén theo tên. Để có được thông tin về một tập tin cụ thể trong tập tin nén, bạn có thể sử dụng phương thức
fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
0 của đối tượng ZipFile. Điều này sẽ cho phép bạn truy cập vào thông tin cụ thể đối với tập tin đó, giống như kích thước nén và chưa nén của tập tin hoặc lần sửa đổi cuối cùng của nó. Chúng ta sẽ quay trở lại điều đó sau.

Gọi phương thức

fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
0 từng cái một trên tất cả các tập tin có thể là một quá trình nhọc nhằn khi có rất nhiều tập tin cần phải được xử lý. Trong trường hợp này, bạn có thể sử dụng phương thức
fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
2 để trả về một danh sách có chứa một đối tượng ZipInfo cho mỗi thành phần trong tập tin nén. Thứ tự của các đối tượng này trong danh sách là giống với các tập tin zip thật sự.

Bạn cũng có thể trực tiếp đọc nội dung của một tập tin cụ thể từ tập tin nén bằng cách sử dụng phương thức

fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
3, trong đó
fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
4 là tên của tập tin bạn muốn đọc. Để làm điều này, tập tin nén phải được mở trong chế độ đọc hoặc nối thêm.

Để có được kích thước nén của một tập tin riêng biệt từ tập tin nén, bạn có thể sử dụng thuộc tính

fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
5. Tương tự như vậy, để biết kích thước chưa nén, bạn có thể sử dụng thuộc tính
fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
6.

Code sau đây sử dụng các thuộc tính và phương thức mà chúng ta vừa mới thảo luận để giải nén chỉ những tập tin có kích thước dưới 1MB.

import zipfile

stories_zip = zipfile.ZipFile('C:\\Stories\\Funny\\archive.zip')

for file in stories_zip.namelist():
    if stories_zip.getinfo(file).file_size < 1024*1024:
		stories_zip.extract(file, 'C:\\Stories\\Short\\Funny')
        
stories_zip.close()

Để biết ngày và giờ khi một tập tin cụ thể từ tập tin nén bị sửa đổi gần đây nhất, bạn có thể sử dụng thuộc tính

fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED)
7. Điều này sẽ trả về một tuple gồm sáu giá trị. Các giá trị sẽ là năm, tháng, ngày, giờ, phút và giây, theo thứ tự cụ thể đó. Năm sẽ luôn luôn được lớn hơn hoặc bằng năm 1980, và giờ, phút và giây là bắt đầu từ 0.

import zipfile

stories_zip = zipfile.ZipFile('C:\\Stories\\Funny\\archive.zip')

thirsty_crow_info = stories_zip.getinfo('The Thirsty Crow.pdf')

print(thirsty_crow_info.date_time)
print(thirsty_crow_info.compress_size)
print(thirsty_crow_info.file_size)
        
stories_zip.close()

Thông tin về kích thước tập tin gốc và kích thước tập tin nén có thể giúp bạn quyết định có nên nén một tập tin hay không. Tôi chắc rằng nó cũng có thể được sử dụng trong một số trường khác.

Tổng kết

Rõ ràng, sử dụng mô-đun

import os
import zipfile

fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w')

for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED)

fantasy_zip.close()
8 để nén tập tin cung cấp cho bạn rất nhiều tính linh hoạt. Bạn có thể nén các tập tin khác nhau trong một thư mục thành các tập tin nén khác nhau dựa trên loại, tên hoặc kích thước của chúng. Bạn cũng có thể quyết định xem bạn có muốn giữ lại cấu trúc thư mục hay không. Tương tự, khi giải nén các tập tin, bạn có thể giải nén chúng đến vị trí bạn muốn, dựa trên tiêu chí riêng của bạn như kích thước, vv.

Thật tình, tôi thấy cũng khá thú vị khi nén và giải nén tập tin bằng cách viết code của riêng mình. Tôi hy vọng bạn thích hướng dẫn này, và nếu bạn có bất kỳ câu hỏi nào, xin vui lòng cho tôi biết trong phần bình luận nhé.