2015-09-19 1 views
0

Когда я использую zipfile.ZipFile.writestr, после этого файл содержит правильное количество символов, но все они являются нулевыми байтами.Модуль zipfile Python добавляет файлы с нулевыми байтами вместо правильного содержимого

Минимальный пример:

import zipfile 
z=zipfile.ZipFile("test.zip", "w") 
z.writestr("foo", "test") 
z.close() 

Полученный test.zip имеет файл "Foo" внутри, который содержит 4 нулевых байтов.

+0

Это хорошо работает для меня. – ForceBru

+1

Действительно. Это «ark» (программа архива kde), которая не может открыть или извлечь ее правильно. «разархивировать» на командной строке, а файл-ролик - отлично. С другой стороны, ark обрабатывает другие zip-файлы с текстовыми файлами внутри без каких-либо проблем. – allo

ответ

0

Кажется, это не проблема с python, а его единственный «ковчег», который не может открыть этот файл. С другой стороны, он каким-то образом закодирован, что ковчег не может его прочитать (в то время как другие программы могут распаковываться).

+0

Принимая это, поскольку у арка есть проблема, а не общий zipfile. Если кто-то знает, что на самом деле вызывает это и как строить почтовые программы, которые обрабатываются правильно всеми архивными программами, я отвечу на ваш ответ. – allo

+0

снова удалил принятый атрибут, так как кажется непонятным, является ли проблема с ark или zipfile. – allo

1

Похожая проблема, и кажется, что ZipInfo является очевидным обходным решением.

import zipfile, os 

name = 'foo.txt' 
data = b'This is a test text.' 

open(name, 'wb').write(data) 
zipfile.ZipFile('write.zip', 'w').write(name)    # OK for Ark 
zipfile.ZipFile('writestr.zip', 'w').writestr(name, data) # nulls by Ark 

wrt_attr = zipfile.ZipFile('write.zip').getinfo(name) 
wrts_attr = zipfile.ZipFile('writestr.zip').getinfo(name) 

os.remove(name) 
os.remove('write.zip') 
os.remove('writestr.zip') 

for attr in wrt_attr.__slots__: 
    if getattr(wrt_attr, attr) != getattr(wrts_attr, attr): 
     attr, getattr(wrt_attr, attr), getattr(wrts_attr, attr) 

attr = 'external_attr' 
oct(getattr(wrt_attr, attr)>>16), oct(getattr(wrts_attr, attr)>>16) 

ZIP spec говорит, external_attr должен быть установлен равным нулю, если содержание пришло из stdin. Однако writestr создает invalid external_attr, когда первым аргументом является str.

Это может быть

0o100xxx (regular file with umasked permission) 

или

zero (as the spec) 

но не

0oxxx (file type absent) 
+0

Так это ошибка python (zipfile)? И почему ввод из писем требует другой обработки, чем обычный файл? Имеет ли он какой-то атрибут, что данные могут быть добавлены, что не работает, когда оно включено в качестве «файла» или что там есть? Просто любопытно. И на строке 1096 '' zinfo.external_attr = 0o600 << 16'' выглядит как у кого-то есть идея, что он делает, но, к сожалению, он не документировал, почему это так. – allo

Смежные вопросы