2014-10-23 1 views
0

Я пытаюсь создать класс, который создает .zip в памяти, содержимое которой может быть любым файлом с любым форматом для его использования позже. Я нашел полезный код и построил этот класс:Python, как создать zip-файл в памяти, чьи файлы, содержащиеся в нем, могут иметь любой формат (.txt, .jpg и т. Д.)

import zipfile 
import StringIO 


class InMemoryZip(object): 
    def __init__(self): 
     # Create the in-memory file-like object 
     self.in_memory_zip = StringIO.StringIO() 

    def append(self, filename_in_zip, file_contents): 
     '''Appends a file with name filename_in_zip and contents of 
     file_contents to the in-memory zip.''' 
     # Get a handle to the in-memory zip in append mode 
     zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) 

     # Write the file to the in-memory zip 
     zf.writestr(filename_in_zip, file_contents) 

     zf.close() 

     return self 

    def read(self): 
     '''Returns a string with the contents of the in-memory zip.''' 
     self.in_memory_zip.seek(0) 
     return self.in_memory_zip.read() 

    def writetofile(self, filename): 
     '''Writes the in-memory zip to a file.''' 
     f = file(filename, "w") 
     f.write(self.read()) 
     f.close() 

# Run a test 
if __name__ == "__main__": 
    imz = InMemoryZip() 
    imz.append("samples/main.cpp", "//Hello code").append("samples/bee.jpg", open('bee.jpg', 'rb').read()) 
    imz.writetofile("test.zip") 

Он отлично работает, если я только пытаюсь сжать текстовые файлы, но я получаю испорченные файлы почтового индекса с .jpg, .png, ... Я смотрел на некоторые примеры, но не любое подобное, потому что все, что я нашел, что это почти то же самое у меня, как example1 или example2

следующие code работ (но не в памяти):

import zipfile 
import glob, os 

# open the zip file for writing, and write stuff to it 

file = zipfile.ZipFile("test.zip", "w") 

for name in glob.glob("samples/*"): 
    file.write(name, os.path.basename(name), zipfile.ZIP_DEFLATED) 

file.close() 

# open the file again, to see what's in it 

file = zipfile.ZipFile("test.zip", "r") 
for info in file.infolist(): 
    print info.filename, info.date_time, info.file_size, info.compress_size 

Затем я должен использовать BytesIO для изображений, исполняемых файлов, .. .? Должен ли я распознавать формат файлов?

Примечание: Моя ОС Windows, 8,1 x64

+0

Я тестировал его, и он работает на моей стороне: есть ли что-то еще? –

+0

Вы пробовали '' 'BytesIO''' (для всех типов)? – wwii

+0

@ MicheleD'Amico, вы пытались открыть, после сжатия, * .png или * .jpg, и это сработало? Вы видели исходное изображение? – fenix688

ответ

1

ОС Windows? В этом случае вам нужно изменить способ открыть файл в тестовом коде (обратите внимание на "b"):

f = file(filename, "wb") 

почтовый файл содержит по существу случайное сочетание байт. Некоторые из этих байтов в конечном итоге будут \n, и если вы не откроете файл в двоичном режиме, они будут преобразованы в \r\n. Это повредит файл.

Это просто совпадение, что это случилось с текстовыми файлами, возможно, потому, что они были маленькими.

+0

большое спасибо! Оно работает! Я не понял, чтобы изменить его на «wb»! :( – fenix688

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