Extraer zip a la memoria, analizar contenidos

Quiero leer el contenido de un archivo zip en la memoria en lugar de extraerlo en un disco, encontrar un archivo en particular en el archivo, abrir el archivo y extraer una línea de él.

¿Se puede abrir y analizar una instancia de StringIO? Sugerencias? Gracias por adelantado.

zfile = ZipFile('name.zip', 'r') for name in zfile.namelist(): if fnmatch.fnmatch(name, '*_readme.xml'): name = StringIO.StringIO() print name # prints StringIO instances open(name, 'r') # IO Error: No such file or directory... 

Encontré algunas publicaciones similares, pero ninguna que parezca abordar este problema: ¿ Extraer un archivo zip a la memoria?

OMI simplemente usando la read es suficiente:

 zfile = ZipFile('name.zip', 'r') files = [] for name in zfile.namelist(): if fnmatch.fnmatch(name, '*_readme.xml'): files.append(zfile.read(name)) 

Esto hará una lista con el contenido de los archivos que calculan el patrón.

Prueba: A continuación, puede analizar el contenido después de las salas iterando a través de la lista:

 for file in files: print(file[0:min(35,len(file))].decode()) # "parsing" 

O mejor usa un funtor:

 import zipfile as zip import os import fnmatch zip_name = os.sys.argv[1] zfile = zip.ZipFile(zip_name, 'r') def parse(contents, member_name = ""): if len(member_name) > 0: print( "Parsed `{}`:".format(member_name) ) print(contents[0:min(35, len(contents))].decode()) # "parsing" for name in zfile.namelist(): if fnmatch.fnmatch(name, '*.cpp'): parse(zfile.read(name), name) 

De esta manera no hay datos guardados en la memoria sin motivo y la huella de la memoria es más pequeña. Puede ser importante si los archivos son grandes.

La pregunta que vincula le muestra que necesita leer el archivo. Dependiendo de su caso de uso, eso ya puede ser suficiente. En su código, reemplaza la variable de bucle que contiene un nombre de archivo con un búfer de cadena vacío. Intenta algo como esto:

 zfile = ZipFile('name.zip', 'r') for name in zfile.namelist(): if fnmatch.fnmatch(name, '*_readme.xml'): ex_file = zfile.open(name) # this is a file like object content = ex_file.read() # now file-contents are a single string 

Si realmente desea un búfer que pueda manipular, simplemente cree una instancia con el contenido:

 buf = StringIO(zfile.open(name).read()) 

También es posible que desee consultar BytesIO y observar que hay diferencias entre Python 2 y 3.

No lo pienses demasiado. Simplemente funciona:

 import zipfile # 1) I want to read the contents of a zip file ... with zipfile.ZipFile('A-Zip-File.zip') as zipper: # 2) ... find a particular file in the archive, open the file ... with zipper.open('A-Particular-File.txt') as fp: # 3) ... and extract a line from it. first_line = fp.readline() print first_line 

Gracias a todos los que contribuyeron con soluciones. Esto es lo que terminó trabajando para mí:

 zfile = ZipFile('name.zip', 'r') for name in zfile.namelist(): if fnmatch.fnmatch(name, '*_readme.xml'): zopen = zfile.open(name) for line in zopen: if re.match('(.*)(.*)(.*)', line): print line