2010-09-08 69 views
11

Tôi đang sử dụng đoạn mã sau để giải nén một file tar:Đầu ra tiến trình tarfile của Python?

import tarfile 
tar = tarfile.open("sample.tar.gz") 
tar.extractall() 
tar.close() 

Tuy nhiên, tôi muốn giữ các tab trên các tiến bộ trong các hình thức của các tập tin đang được chiết xuất vào lúc này. Tôi có thể làm cái này như thế nào?

ĐIỂM THƯỞNG THÊM: có thể tạo phần trăm của quá trình trích xuất không? Tôi muốn sử dụng nó cho tkinter để cập nhật một thanh tiến trình. Cảm ơn!

Trả lời

6

Cả hai tập tin tiến độ và ủng hộ toàn cầu gress:

import tarfile 
import io 
import os 

def get_file_progress_file_object_class(on_progress): 
    class FileProgressFileObject(tarfile.ExFileObject): 
     def read(self, size, *args): 
      on_progress(self.name, self.position, self.size) 
      return tarfile.ExFileObject.read(self, size, *args) 
    return FileProgressFileObject 

class TestFileProgressFileObject(tarfile.ExFileObject): 
    def read(self, size, *args): 
     on_progress(self.name, self.position, self.size) 
     return tarfile.ExFileObject.read(self, size, *args) 

class ProgressFileObject(io.FileIO): 
    def __init__(self, path, *args, **kwargs): 
     self._total_size = os.path.getsize(path) 
     io.FileIO.__init__(self, path, *args, **kwargs) 

    def read(self, size): 
     print("Overall process: %d of %d" %(self.tell(), self._total_size)) 
     return io.FileIO.read(self, size) 

def on_progress(filename, position, total_size): 
    print("%s: %d of %s" %(filename, position, total_size)) 

tarfile.TarFile.fileobject = get_file_progress_file_object_class(on_progress) 
tar = tarfile.open(fileobj=ProgressFileObject("a.tgz")) 
tar.extractall() 
tar.close() 
+0

Đây vẫn là con khỉ. ':)' –

+0

Cảm ơn tokland, công trình này :) Bất kỳ cách nào để nhận được một phao của quá trình khai thác tổng thể? – FLX

+0

Để cụ thể hơn, có cách nào để nhận được kích thước không nén trước khi bắt đầu quá trình trích xuất không? – FLX

3

Bạn có thể sử dụng extract thay vì extractall - bạn sẽ có thể in tên thành viên khi chúng đang được trích xuất. Để có danh sách thành viên, bạn có thể sử dụng getmembers.

Một thư viện progressbar văn bản có thể được tìm thấy ở đây:

đoạn Tkinter:

+1

Nhìn vào mã "extractall" gọi là "chiết xuất ", vì vậy không nên bị phạt tốc độ. – tokland

+0

cảm ơn, đã loại bỏ 'chưa được đoán' của tôi ... – miku

+0

Ghi chú tài liệu "Phương thức trích xuất() không quan tâm đến một số vấn đề khai thác. Trong hầu hết các trường hợp, bạn nên cân nhắc sử dụng phương thức extractall()." Không biết những vấn đề khai thác đó là gì, tôi do dự khi chỉ trao đổi 'trích xuất' cho' extractall'. –

4

Bạn có thể chỉ định tham số members trong extractall()

with tarfile.open(<path>, 'r') as tarball: 
    tarball.extractall(path=<some path>, members = track_progress(tarball)) 

def track_progress(members): 
    for member in members: 
     # this will be the current file being extracted 
     yield member 

memberTarInfo đối tượng, xem tất cả các chức năng có sẵn và tài sản here

+2

Để điền thông tin này, sau khi 'thành viên lợi nhuận' bạn có thể in ra tên hoặc cập nhật thanh tiến trình. –

2

Có một giải pháp tuyệt vời ở đây đó sẽ ghi đè các module tarfile như là một thay thế thả và cho phép bạn chỉ định một cuộc gọi lại để cập nhật.

https://github.com/thomaspurchas/tarfile-Progress-Reporter/

cập nhật dựa trên nhận xét

+0

Thư viện đó đã sẵn sàng để sản xuất, ví dụ: sử dụng các biến chưa được gán khi không truyền hàm tiến triển ... chuyển một chuỗi đường dẫn đến trích xuất không thành công, vì nó mong đợi một tarinfo (mặc dù cả hai tùy chọn đều có thể) – andsens

1

Để xem những tập tin hiện đang được chiết xuất, sau đây làm việc cho tôi:

import tarfile 

print "Extracting the contents of sample.tar.gz:" 
tar = tarfile.open("sample.tar.gz") 

for member_info in tar.getmembers(): 
    print "- extracting: " + member_info.name 
    tar.extract(member_info) 

tar.close() 
Các vấn đề liên quan