2012-05-13 42 views
9

Tôi có nhiều tệp zip có cùng cấu trúc - chúng chứa các tệp XML ở cấp cơ sở. Tất cả các tệp trong mỗi tệp zip là duy nhất (không có bản sao trên các tệp zip). Tôi cần phải kết hợp tất cả các tệp XML từ tất cả các tệp zip vào một tệp zip duy nhất (với cấu trúc giống như các tệp zip gốc). Gợi ý cho cách tốt nhất để làm điều này? Cảm ơn.Hợp nhất nhiều tệp zip vào một tệp zip duy nhất trong Python

+3

Giải nén tất cả và tạo một cái mới? – sarnold

+3

Đó sẽ là cách tiếp cận rõ ràng nhất. Bạn cũng có thể chọn một tệp zipfile cuối cùng, trích xuất các tệp từ những người khác và thêm chúng vào tệp cuối cùng, nhưng không chắc chắn nó sẽ nhanh hơn. – jgritty

+0

Xin cảm ơn @sarnold. Tôi cũng đã nghĩ đến cách tiếp cận này, nhưng không chắc liệu có cách nào thanh lịch hơn để làm điều đó hay không. –

Trả lời

11

Đây là phiên bản ngắn nhất tôi có thể đưa ra:

>>> import zipfile as z 
>>> z1 = z.ZipFile('z1.zip', 'a') 
>>> z2 = z.ZipFile('z2.zip', 'r') 
>>> z1.namelist() 
['a.xml', 'b.xml'] 
>>> z2.namelist() 
['c.xml', 'd.xml'] 
>>> [z1.writestr(t[0], t[1].read()) for t in ((n, z2.open(n)) for n in z2.namelist())] 
[None, None] 
>>> z1.namelist() 
['a.xml', 'b.xml', 'c.xml', 'd.xml'] 
>>> z1.close() 

Nếu không có thử nghiệm giải pháp thay thế, với tôi đây là tốt nhất (và có lẽ rõ ràng nhất quá!) Giải pháp bởi vì - giả sử cả hai tập tin zip chứa cùng một lượng dữ liệu, phương pháp này yêu cầu giải nén và nén lại chỉ một nửa của nó (1 tệp).

PS: Danh sách hiểu là chỉ để giữ các hướng dẫn trên một dòng trong bảng điều khiển (tốc độ gỡ lỗi lên). Mã pythonic tốt sẽ yêu cầu một vòng lặp for thích hợp, với điều kiện danh sách kết quả không có mục đích ...

HTH!

+0

Cảm ơn, mặc dù tôi sẽ có một số lượng tệp zip khác nhau, vì vậy tôi cần một cách tiếp cận chung chung hơn. –

+1

@DaveCrumbacher: trừ khi tôi hiểu lầm bạn, tất cả những gì bạn phải làm để sử dụng phương pháp này để hợp nhất nhiều tệp, là thêm vòng lặp: 'cho zfile trong (z2, z3, z4, ...)' ... hoặc tôi đang thiếu một cái gì đó? – mac

+0

Có, @mac, bạn nói đúng. Cảm ơn. –

6

Đây là những gì tôi nghĩ ra, nhờ @mac. Lưu ý rằng cách này hiện đang được triển khai thực hiện tệp zip đầu tiên được sửa đổi để chứa tất cả các tệp từ các tệp zip khác.

import zipfile as z 

zips = ['z1.zip', 'z2.zip', 'z3.zip'] 

""" 
Open the first zip file as append and then read all 
subsequent zip files and append to the first one 
""" 
with z.ZipFile(zips[0], 'a') as z1: 
    for fname in zips[1:]: 
     zf = z.ZipFile(fname, 'r') 
     for n in zf.namelist(): 
      z1.writestr(n, zf.open(n).read()) 
+5

'zipfile.ZipFile()' cũng là một trình quản lý ngữ cảnh, vì vậy bạn có thể thay thế 'z1.close()' bằng một 'với z.ZipFile (zips [0], 'a') thành z1:' và thụt lề mã tiếp theo. Cùng với các đối tượng đọc. – glglgl

+2

Cảm ơn @glglgl. Tôi đã cập nhật câu trả lời của mình để phản ánh cách tiếp cận này. –

Các vấn đề liên quan