Tệp PKZIP có cấu trúc cao và chỉ nối thêm vào cuối sẽ làm hỏng lên. Tôi không thể nói với các phiên bản trước đó, nhưng giải pháp cho vấn đề này là mở một tệp zip để đọc, mở một tệp mới để viết, trích xuất nội dung đầu tiên và sau đó thêm các thành phần bổ sung của bạn vào cuối. Khi hoàn thành, hãy thay thế tệp zip gốc bằng tệp zip mới được tạo.
Các traceback tôi nhận được khi chạy mã của bạn khi chạy mã của bạn là:
Traceback (most recent call last):
File "zip.py", line 19, in <module>
Foo()
File "zip.py", line 17, in Foo
print zip.read("bar")
File "/usr/lib/python2.6/zipfile.py", line 834, in read
return self.open(name, "r", pwd).read()
File "/usr/lib/python2.6/zipfile.py", line 874, in open
zinfo.orig_filename, fname)
zipfile.BadZipfile: File name in directory "bar" and header "foo" differ.
Sau khi kiểm tra chặt chẽ hơn, tôi nhận thấy rằng bạn đang đọc từ một tập tin giống như StringIO mở với 'chế độ a'ppend mà nên kết quả trong một lỗi đọc vì 'a' không thể đọc được, và chắc chắn phải tìm kiếm() ed giữa các lần đọc và viết. Tôi sẽ đánh lừa một số và cập nhật điều này.
Cập nhật:
Sau khi bị đánh cắp khá nhiều tất cả các mã này từ Doug Hellmann của tuyệt vời Python Module of the Week, tôi thấy rằng nó hoạt động khá nhiều như tôi mong đợi. Người ta có thể không chỉ đơn thuần là thêm vào một tập tin PKZIP có cấu trúc, và nếu mã trong các bài bản gốc bao giờ đã làm việc, đó là một cách tình cờ:
import zipfile
import datetime
def create(archive_name):
print 'creating archive'
zf = zipfile.ZipFile(archive_name, mode='w')
try:
zf.write('/etc/services', arcname='services')
finally:
zf.close()
def print_info(archive_name):
zf = zipfile.ZipFile(archive_name)
for info in zf.infolist():
print info.filename
print '\tComment:\t', info.comment
print '\tModified:\t', datetime.datetime(*info.date_time)
print '\tSystem:\t\t', info.create_system, '(0 = Windows, 3 = Unix)'
print '\tZIP version:\t', info.create_version
print '\tCompressed:\t', info.compress_size, 'bytes'
print '\tUncompressed:\t', info.file_size, 'bytes'
print
zf.close()
def append(archive_name):
print 'appending archive'
zf = zipfile.ZipFile(archive_name, mode='a')
try:
zf.write('/etc/hosts', arcname='hosts')
finally:
zf.close()
def expand_hosts(archive_name):
print 'expanding hosts'
zf = zipfile.ZipFile(archive_name, mode='r')
try:
host_contents = zf.read('hosts')
finally:
zf.close
zf = zipfile.ZipFile(archive_name, mode='a')
try:
zf.writestr('hosts', host_contents + '\n# hi mom!')
finally:
zf.close()
def main():
archive = 'zipfile.zip'
create(archive)
print_info(archive)
append(archive)
print_info(archive)
expand_hosts(archive)
print_info(archive)
if __name__ == '__main__': main()
đáng chú ý là sản phẩm từ các cuộc gọi cuối cùng để print_info
:
...
hosts
Modified: 2010-05-20 03:40:24
Compressed: 404 bytes
Uncompressed: 404 bytes
hosts
Modified: 2010-05-27 11:46:28
Compressed: 414 bytes
Uncompressed: 414 bytes
Nó không gắn thêm vào 'tên máy chủ' hiện có, nó tạo ra một thành viên lưu trữ bổ sung.
"Je n'ai fait celle-ci cộng longue que parce que je n'ai pas le eu Loisir de la faire cộng courte."
- Blaise Pascal định dạng file