В настоящее время я пишу библиотеку с открытым исходным кодом для формата контейнера, которая включает в себя изменение zip-архивов. Поэтому я использовал встроенный zipfile-модуль pythons. Из-за некоторых ограничений я решил изменить модуль и отправить его в свою библиотеку. Эти изменения включают в себя патч для удаления записей из zip-файла из трекера для отслеживания ошибок python: https://bugs.python.org/issue6818 Чтобы быть более конкретным, я включил zipfile.remove.2.patch
из ubershmekel. После некоторых изменений для Python-2.7 патч работает просто отлично в соответствии с отгруженными модульными тестами.Python удалить запись из zipfile
Но тем не менее я сталкиваюсь с некоторыми проблемами при удалении, добавлении и удалении + добавлении файлов без закрытия zip-файла между ними.
Error
Traceback (most recent call last):
File "/home/martin/git/pyCombineArchive/tests/test_zipfile.py", line 1590, in test_delete_add_no_close
self.assertEqual(zf.read(fname), data)
File "/home/martin/git/pyCombineArchive/combinearchive/custom_zip.py", line 948, in read
with self.open(name, "r", pwd) as fp:
File "/home/martin/git/pyCombineArchive/combinearchive/custom_zip.py", line 1003, in open
% (zinfo.orig_filename, fname))
BadZipFile: File name in directory 'foo.txt' and header 'bar.txt' differ.
Значение zip-файла в порядке, но почему-то центральный словарь/заголовок заголовка перепутаны. Это UnitTest воспроизводит эту ошибку:
def test_delete_add_no_close(self):
fname_list = ["foo.txt", "bar.txt", "blu.bla", "sup.bro", "rollah"]
data_list = [''.join([chr(randint(0, 255)) for i in range(100)]) for i in range(len(fname_list))]
# add some files to the zip
with zipfile.ZipFile(TESTFN, "w") as zf:
for fname, data in zip(fname_list, data_list):
zf.writestr(fname, data)
for no in range(0, 2):
with zipfile.ZipFile(TESTFN, "a") as zf:
zf.remove(fname_list[no])
zf.writestr(fname_list[no], data_list[no])
zf.remove(fname_list[no+1])
zf.writestr(fname_list[no+1], data_list[no+1])
# try to access prior deleted/added file and prior last file (which got moved, while delete)
for fname, data in zip(fname_list, data_list):
self.assertEqual(zf.read(fname), data)
Мой модифицированный ZipFile модуль и полный файл UnitTest можно найти в этом суть: https://gist.github.com/FreakyBytes/30a6f9866154d82f1c3863f2e4969cc4