Làm thế nào để tạo tệp tar nén đầy đủ bằng Python?


Câu trả lời:


186

Để xây dựng .tar.gz(hay còn gọi là .tgz) cho toàn bộ cây thư mục:

import tarfile
import os.path

def make_tarfile(output_filename, source_dir):
    with tarfile.open(output_filename, "w:gz") as tar:
        tar.add(source_dir, arcname=os.path.basename(source_dir))

Thao tác này sẽ tạo một kho lưu trữ tar được gzipped chứa một thư mục cấp cao nhất có cùng tên và nội dung như source_dir.


31
Chỉ là một lưu ý cho người đọc, nếu bạn bỏ qua arcname=os.path.basename(source_dir)thì nó sẽ cung cấp cho bạn toàn bộ cấu trúc đường dẫn của source_dirtệp tar (trong hầu hết các trường hợp, điều đó có thể bất tiện).
Brōtsyorfuzthrāx

12
Một lưu ý thứ hai; sử dụng arcname=os.path.basename(source_dir)vẫn có nghĩa là kho lưu trữ chứa một thư mục chứa nội dung của source_dir. Nếu bạn muốn gốc của kho lưu trữ chứa chính nội dung chứ không phải nội dung trong thư mục, hãy sử dụng arcname=os.path.septhay thế.
Jonathan H

2
@Sheljohn rất tiếc, điều này không hoàn toàn chính xác, bởi vì nếu ai đó sử dụng os.path.sep, thì kho lưu trữ sẽ chứa dịch vụ "." hoặc thư mục "/" thường không phải là vấn đề, nhưng đôi khi nó có thể là vấn đề nếu sau đó bạn xử lý tệp lưu trữ này theo chương trình. Có vẻ như cách duy nhất thực sự rõ ràng là thực hiện os.walkvà thêm các tệp riêng lẻ
The Godfather

Để loại bỏ tất cả cấu trúc thư mục, chỉ cần sử dụng arcname='.'. Không cần sử dụng os.walk.
edouardtheron

85
import tarfile
tar = tarfile.open("sample.tar.gz", "w:gz")
for name in ["file1", "file2", "file3"]:
    tar.add(name)
tar.close()

Nếu bạn muốn tạo tệp nén tar.bz2, chỉ cần thay thế tên phần mở rộng tệp bằng ".tar.bz2" và "w: gz" bằng "w: bz2".


10
Bạn thực sự nên sử dụng with tarfile.open( ..bằng Python, thay vì gọi openclosethủ công. Đây cũng là trường hợp khi mở các tệp thông thường.
Jonathan H

31

Bạn gọi tarfile.open với mode='w:gz', nghĩa là "Mở để viết nén gzip."

Có thể bạn sẽ muốn kết thúc tên tệp ( nameđối số là open) bằng .tar.gz, nhưng điều đó không ảnh hưởng đến khả năng nén.

BTW, bạn thường nén tốt hơn với một chế độ 'w:bz2', giống như tarcó thể thường nén thậm chí tốt hơn với bzip2chế độ nén gzip.


6
Chỉ cần lưu ý nhanh rằng tên tệp cho tarball nén bzip2 phải kết thúc bằng ".tar.bz2".
Ignacio Vazquez-Abrams

8

Các câu trả lời trước khuyên bạn nên sử dụng tarfilemô-đun Python để tạo .tar.gztệp bằng Python. Đó rõ ràng là một giải pháp tốt và kiểu Python, nhưng nó có nhược điểm nghiêm trọng về tốc độ lưu trữ. Câu hỏi này đề cập đến tarfiletốc độ chậm hơn khoảng hai lần so với tartiện ích trong Linux. Theo kinh nghiệm của tôi ước tính này là khá chính xác.

Vì vậy, để lưu trữ nhanh hơn, bạn có thể sử dụng tarlệnh sử dụng subprocessmô-đun:

subprocess.call(['tar', '-czf', output_filename, file_to_archive])

0

Trong tệp tar.gz này, nén tệp trong thư mục dạng xem đang mở Trong giải quyết, hãy sử dụng os.path.basename (file_directory)

with tarfile.open("save.tar.gz","w:gz"):
      for file in ["a.txt","b.log","c.png"]:
           tar.add(os.path.basename(file))

nó sử dụng trong nén tệp tar.gz trong thư mục


0

Ngoài câu trả lời của @Aleksandr Tukallo, bạn cũng có thể nhận được đầu ra và thông báo lỗi (nếu xảy ra). Nén một thư mục bằng cách sử dụng tarđược giải thích khá tốt trong câu trả lời sau đây .

import traceback
import subprocess

try:
    cmd = ['tar', 'czfj', output_filename, file_to_archive]
    output = subprocess.check_output(cmd).decode("utf-8").strip() 
    print(output)          
except Exception:       
    print(f"E: {traceback.format_exc()}")       
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.