una txt ruta recorrer que nombre manejo libreria leer importar hace gestion escribir directorios carpeta archivos archivo python unzip

txt - python recorrer archivos de una carpeta



Descomprimiendo la estructura de directorios con python (9)

Tengo un archivo zip que contiene la siguiente estructura de directorios:

dir1/dir2/dir3a dir1/dir2/dir3b

Estoy intentando descomprimirlo y mantener la estructura del directorio, sin embargo, recibo el error:

IOError: [Errno 2] No such file or directory: ''C:///projects///testFolder///subdir///unzip.exe''

donde testFolder es dir1 arriba y subdir es dir2.

¿Hay una manera rápida de descomprimir el archivo y mantener la estructura del directorio?


Filtrar lista de nombres para excluir las carpetas.

Todo lo que tienes que hacer es filtrar las entradas namelist() que terminan con / y el problema se resuelve:

z.extractall(dest, filter(lambda f: not f.endswith(''/''), z.namelist()))

nJoy!


Hay una forma muy fácil si está utilizando Python 2.6: el método extractall .

Sin embargo, dado que el módulo zipfile se implementa completamente en Python sin ninguna extensión C, probablemente pueda copiarlo de una instalación 2.6 y usarlo con una versión anterior de Python; Puede encontrar esto más fácil que tener que volver a implementar la funcionalidad usted mismo. Sin embargo, la función en sí es bastante corta:

def extractall(self, path=None, members=None, pwd=None): """Extract all members from the archive to the current working directory. `path'' specifies a different directory to extract to. `members'' is optional and must be a subset of the list returned by namelist(). """ if members is None: members = self.namelist() for zipinfo in members: self.extract(zipinfo, path, pwd)


Los métodos extract y extractall son excelentes si estás en Python 2.6. Tengo que usar Python 2.5 por ahora, así que solo necesito crear los directorios si no existen. Puede obtener una lista de directorios con el método namelist() . Los directorios siempre terminarán con una barra diagonal (incluso en Windows), por ejemplo,

import os, zipfile z = zipfile.ZipFile(''myfile.zip'') for f in z.namelist(): if f.endswith(''/''): os.makedirs(f)

Probablemente no querrá hacerlo exactamente así (es decir, probablemente querrá extraer el contenido del archivo zip a medida que pasa por la lista de nombres), pero se le ocurre la idea.


Parece que está intentando ejecutar descomprimir para extraer el zip.

Sería mejor utilizar el módulo zipfile python y, por lo tanto, realizar la extracción en python.

import zipfile def extract(zipfilepath, extractiondir): zip = zipfile.ZipFile(zipfilepath) zip.extractall(path=extractiondir)


Probé esto, y puedo reproducirlo. El método extractall, como lo sugieren otras respuestas, no resuelve el problema. Esto me parece un error en el módulo zipfile (¿quizás solo para Windows?), A menos que no entienda cómo están estructurados los archivos zip.

testa/ testa/testb/ testa/testb/test.log > test.zip >>> from zipfile import ZipFile >>> zipTest = ZipFile("C://...//test.zip") >>> zipTest.extractall("C://...//") Traceback (most recent call last): File "<stdin>", line 1, in <module> File ".../zipfile.py", line 940, in extractall File ".../zipfile.py", line 928, in extract File ".../zipfile.py", line 965, in _extract_member IOError: [Errno 2] No such file or directory: ''C://...//testa//testb//test.log''

Si hago un printdir() , obtengo esto (primera columna):

>>> zipTest.printdir() File Name testa/testb/ testa/testb/test.log

Si intento extraer solo la primera entrada, así:

>>> zipTest.extract("testa/testb/") ''C://...//testa//testb''

En el disco, esto da como resultado la creación de una carpeta testa , con un archivo testb dentro. Aparentemente, esta es la razón por la que el intento posterior de extraer test.log falla; testa/testb es un archivo, no una carpeta.

Edición # 1: Si solo extraes el archivo, entonces funciona:

>>> zipTest.extract("testa/testb/test.log") ''C://...//testa//testb//test.log''

Edición # 2: el código de Jeff es el camino a seguir; iterar a través de la lista de namelist ; Si es un directorio, crea el directorio. De lo contrario, extraiga el archivo.


Sé que puede ser un poco tarde para decir esto, pero Jeff tiene razón. Es tan simple como:

import os from zipfile import ZipFile as zip def extractAll(zipName): z = zip(zipName) for f in z.namelist(): if f.endswith(''/''): os.makedirs(f) else: z.extract(f) if __name__ == ''__main__'': zipList = [''one.zip'', ''two.zip'', ''three.zip''] for zip in zipList: extractAll(zipName)


Si como yo, tienes que extraer un archivo zip completo con una versión anterior de Python (en mi caso, 2.4), esto es lo que se me ocurrió (basado en la respuesta de Jeff):

import zipfile import os def unzip(source_file_path, destination_dir): destination_dir += ''/'' z = zipfile.ZipFile(source_file_path, ''r'') for file in z.namelist(): outfile_path = destination_dir + file if file.endswith(''/''): os.makedirs(outfile_path) else: outfile = open(outfile_path, ''wb'') outfile.write(z.read(file)) outfile.close() z.close()


Tenga en cuenta que los archivos zip pueden tener entradas para directorios y archivos. Al crear archivos con el comando zip , pase la opción -D para desactivar la adición explícita de entradas de directorio al archivo. Cuando el método ZipFile.extractall Python 2.6 se ejecuta en una entrada de directorio, parece crear un archivo en su lugar. Dado que las entradas del archivo no están necesariamente en orden, esto hace que ZipFile.extractall falle con bastante frecuencia, ya que intenta crear un archivo en un subdirectorio de un archivo. Si tiene un archivo que desea usar con el módulo Python, simplemente extráigalo y vuelva a comprimirlo con la opción -D . Aquí hay un pequeño fragmento de código que he estado usando durante un tiempo para hacer exactamente eso:

P=`pwd` && Z=`mktemp -d -t zip` && pushd $Z && unzip $P/<busted>.zip && zip -r -D $P/<new>.zip . && popd && rm -rf $Z

Reemplace <busted>.zip y <new>.zip con nombres de archivo reales relativos al directorio actual. Luego copie todo y péguelo en un shell de comandos, y creará un nuevo archivo que está listo para rockear con Python 2.6. Hay un comando zip que eliminará estas entradas de directorio sin descomprimir, pero IIRC se comportó de manera extraña en diferentes entornos de shell o configuraciones zip.


No confíe en extract () o extractall ().

Estos métodos extraen ciegamente los archivos a las rutas dadas en sus nombres de archivo. Pero los nombres de archivo ZIP pueden ser cualquier cosa, incluidas cadenas peligrosas como "x /../../../ etc / passwd". Extraiga dichos archivos y podría haber comprometido todo su servidor.

Tal vez esto debería considerarse un agujero de seguridad reportable en el módulo zipfile de Python, pero cualquier número de zip-dearchivers ha mostrado el mismo comportamiento en el pasado. Para desarchivar un archivo ZIP con estructura de carpetas de manera segura, necesita una verificación profunda de cada ruta de archivo.