使用python将文件夹添加到一个zip文件
我想创build一个zip文件。 将一个文件夹添加到zip文件,然后将一堆文件添加到该文件夹。
所以我想用一个包含文件的单个文件夹的zip文件结束。
我不知道如果它的不好的做法,有文件夹中的zip文件或东西,但谷歌没有给我任何关于这个问题。
我开始与这个:
def addFolderToZip(myZipFile,folder): folder = folder.encode('ascii') #convert path to ascii for ZipFile Method for file in glob.glob(folder+"/*"): if os.path.isfile(file): print file myZipFile.write(file, os.path.basename(file), zipfile.ZIP_DEFLATED) elif os.path.isdir(file): addFolderToZip(myZipFile,file) def createZipFile(filename,files,folders): curTime=strftime("__%Y_%m_%d", time.localtime()) filename=filename+curTime; print filename zipFilename=utils.getFileName("files", filename+".zip") myZipFile = zipfile.ZipFile( zipFilename, "w" ) # Open the zip file for writing for file in files: file = file.encode('ascii') #convert path to ascii for ZipFile Method if os.path.isfile(file): (filepath, filename) = os.path.split(file) myZipFile.write( file, filename, zipfile.ZIP_DEFLATED ) for folder in folders: addFolderToZip(myZipFile,folder) myZipFile.close() return (1,zipFilename) (success,filename)=createZipFile(planName,files,folders);
取自: http : //mail.python.org/pipermail/python-list/2006-August/396166.html
其中摆脱所有文件夹,并将目标文件夹(及其子文件夹)中的所有文件放入一个zip文件。 我无法得到它来添加一个完整的文件夹。
如果我将path提供给myZipFile.write中的一个文件夹,我会得到
IOError:[Errno 13] Permission denied:'.. \ packed \ bin'
任何帮助是非常受欢迎的。
相关问题: 如何使用python(版本2.5)压缩文件夹的内容?
好吧,我明白你想要什么之后,就像使用zipfile.write
的第二个参数一样简单,你可以使用任何你想要的:
import zipfile myZipFile = zipfile.ZipFile("zip.zip", "w" ) myZipFile.write("test.py", "dir\\test.py", zipfile.ZIP_DEFLATED )
创build一个zip文件,其中test.py
将被提取到一个名为dir
编辑:我曾经有一个zip文件中创build一个空目录:这是可能的。 在上面的代码之后,只要从zip文件中删除test.py文件,文件就不存在了,但是空目录仍然存在。
你也可以使用shutil
import shutil zip_name = 'path\to\zip_file' directory_name = 'path\to\directory' # Create 'path\to\zip_file.zip' shutil.make_archive(zip_name, 'zip', directory_name)
这将把整个文件夹放在zip中。
一个zip文件没有目录结构,只有一堆path名和它们的内容。 这些path名应该相对于一个假想的根文件夹(ZIP文件本身)。 “../”前缀在zip文件中没有定义的含义。
考虑你有一个文件,并且你想把它存储在一个zip文件的“文件夹”中。 您只需在将文件存储在zipfile中时将文件名前缀加上文件夹名称即可:
zipi= zipfile.ZipInfo() zipi.filename= "folder/a" # this is what you want zipi.date_time= time.localtime(os.path.getmtime("a"))[:6] zipi.compress_type= zipfile.ZIP_DEFLATED filedata= open("a", "rb").read() zipfile1.writestr(zipi, filedata) # zipfile1 is a zipfile.ZipFile instance
我不知道任何允许在ZIP文件中包含空文件夹的ZIP实现。 我可以考虑一个解决方法(在压缩文件夹中存储一个虚拟文件名,在提取时应该忽略这个文件名),但不能跨越实现进行移植。
import zipfile import os class ZipUtilities: def toZip(self, file, filename): zip_file = zipfile.ZipFile(filename, 'w') if os.path.isfile(file): zip_file.write(file) else: self.addFolderToZip(zip_file, file) zip_file.close() def addFolderToZip(self, zip_file, folder): for file in os.listdir(folder): full_path = os.path.join(folder, file) if os.path.isfile(full_path): print 'File added: ' + str(full_path) zip_file.write(full_path) elif os.path.isdir(full_path): print 'Entering folder: ' + str(full_path) self.addFolderToZip(zip_file, full_path) def main(): utilities = ZipUtilities() filename = 'TEMP.zip' directory = 'TEMP' utilities.toZip(directory, filename) main()
我在跑:
python tozip.py
这是日志:
havok@fireshield:~$ python tozip.py File added: TEMP/NARF (7ª copia) Entering folder: TEMP/TEMP2 File added: TEMP/TEMP2/NERF (otra copia) File added: TEMP/TEMP2/NERF (copia) File added: TEMP/TEMP2/NARF File added: TEMP/TEMP2/NARF (copia) File added: TEMP/TEMP2/NARF (otra copia) Entering folder: TEMP/TEMP2/TEMP3 File added: TEMP/TEMP2/TEMP3/DOCUMENTO DEL FINAL File added: TEMP/TEMP2/TEMP3/DOCUMENTO DEL FINAL (copia) File added: TEMP/TEMP2/NERF File added: TEMP/NARF (copia) (otra copia) File added: TEMP/NARF (copia) (copia) File added: TEMP/NARF (6ª copia) File added: TEMP/NERF (copia) (otra copia) File added: TEMP/NERF (4ª copia) File added: TEMP/NERF (otra copia) File added: TEMP/NERF (3ª copia) File added: TEMP/NERF (6ª copia) File added: TEMP/NERF (copia) File added: TEMP/NERF (5ª copia) File added: TEMP/NARF (8ª copia) File added: TEMP/NARF (3ª copia) File added: TEMP/NARF (5ª copia) File added: TEMP/NERF (copia) (3ª copia) File added: TEMP/NARF File added: TEMP/NERF (copia) (copia) File added: TEMP/NERF (8ª copia) File added: TEMP/NERF (7ª copia) File added: TEMP/NARF (copia) File added: TEMP/NARF (otra copia) File added: TEMP/NARF (4ª copia) File added: TEMP/NERF File added: TEMP/NARF (copia) (3ª copia)
正如你所看到的,它的工作,档案也是好的。 这是一个可以压缩整个文件夹的recursion函数。 唯一的问题是,它不会创build一个空的文件夹。
干杯。
以下是将整个目录压缩成zip文件的一些代码。
这似乎可以在Windows和Linux上创buildzip文件。 输出文件似乎在Windows(内置压缩文件夹function,WinZip和7-Zip)和Linux上正确提取。 但是,压缩文件中的空目录似乎是一个棘手的问题。 下面的解决scheme似乎工作,但在Linux上的“zipinfo”的输出是关于。 另外,目录权限没有正确设置为zip存档中的空目录。 这似乎需要更深入的研究。
我从这个速度审查线程和这个Python邮件列表线程得到了一些信息。
请注意,此函数旨在将文件放入zip存档中,不带任何父目录或只有一个父目录,因此它将修剪文件系统path中的所有主目录,并且不会将其包含在zip存档path中。 这通常是这样的情况,当你想要一个目录,并把它变成一个zip文件,可以在不同的位置提取。
关键字参数:
dirPath – 要归档的目录的stringpath。 这是唯一需要的论据。 它可以是绝对的或相对的,但是只有一个或零个主目录将被包括在zip档案中。
zipFilePath – 输出zip文件的stringpath。 这可以是绝对或相对path。 如果zip文件已经存在,它将被更新。 如果不是,它将被创build。 如果您想从头开始replace,请在调用此函数之前将其删除。 (默认值是以dirPath +“.zip”的forms计算的)
includeDirInZip – 指示顶层目录是否应包含在归档中或省略的布尔值。 (默认为True)
(请注意,StackOverflow似乎无法用三重引号string打印我的Python,所以我只是将我的文档string转换为文本文本)
#!/usr/bin/python import os import zipfile def zipdir(dirPath=None, zipFilePath=None, includeDirInZip=True): if not zipFilePath: zipFilePath = dirPath + ".zip" if not os.path.isdir(dirPath): raise OSError("dirPath argument must point to a directory. " "'%s' does not." % dirPath) parentDir, dirToZip = os.path.split(dirPath) #Little nested function to prepare the proper archive path def trimPath(path): archivePath = path.replace(parentDir, "", 1) if parentDir: archivePath = archivePath.replace(os.path.sep, "", 1) if not includeDirInZip: archivePath = archivePath.replace(dirToZip + os.path.sep, "", 1) return os.path.normcase(archivePath) outFile = zipfile.ZipFile(zipFilePath, "w", compression=zipfile.ZIP_DEFLATED) for (archiveDirPath, dirNames, fileNames) in os.walk(dirPath): for fileName in fileNames: filePath = os.path.join(archiveDirPath, fileName) outFile.write(filePath, trimPath(filePath)) #Make sure we get empty directories as well if not fileNames and not dirNames: zipInfo = zipfile.ZipInfo(trimPath(archiveDirPath) + "/") #some web sites suggest doing #zipInfo.external_attr = 16 #or #zipInfo.external_attr = 48 #Here to allow for inserting an empty directory. Still TBD/TODO. outFile.writestr(zipInfo, "") outFile.close()
这里有一些示例用法。 请注意,如果您的dirPath参数有多个主目录,则默认情况下只包含最后一个目录。 通过includeDirInZip = False来省略所有的主要目录。
zipdir("foo") #Just give it a dir and get a .zip file zipdir("foo", "foo2.zip") #Get a .zip file with a specific file name zipdir("foo", "foo3nodir.zip", False) #Omit the top level directory zipdir("../test1/foo", "foo4nopardirs.zip")
这里是我用来压缩文件夹的function:
import os import os.path import zipfile def zip_dir(dirpath, zippath): fzip = zipfile.ZipFile(zippath, 'w', zipfile.ZIP_DEFLATED) basedir = os.path.dirname(dirpath) + '/' for root, dirs, files in os.walk(dirpath): if os.path.basename(root)[0] == '.': continue #skip hidden directories dirname = root.replace(basedir, '') for f in files: if f[-1] == '~' or (f[0] == '.' and f != '.htaccess'): #skip backup files and all hidden files except .htaccess continue fzip.write(root + '/' + f, dirname + '/' + f) fzip.close()
添加一些导入后,你的代码对我来说运行良好,你如何调用脚本,也许你可以告诉我们'.. \ packed \ bin'目录的文件夹结构。
我用下面的参数调用你的代码:
planName='test.zip' files=['z.py',] folders=['c:\\temp'] (success,filename)=createZipFile(planName,files,folders)
`
如果您查看使用Info-ZIP创build的zip文件,则会看到确实列出了目录:
$ zip foo.zip -r foo adding: foo/ (stored 0%) adding: foo/foo.jpg (deflated 84%) $ less foo.zip Archive: foo.zip Length Method Size Cmpr Date Time CRC-32 Name -------- ------ ------- ---- ---------- ----- -------- ---- 0 Stored 0 0% 2013-08-18 14:32 00000000 foo/ 476320 Defl:N 77941 84% 2013-08-18 14:31 55a52268 foo/foo.jpg -------- ------- --- ------- 476320 77941 84% 2 files
请注意,目录条目长度为零,未压缩。 看来你可以用Python来实现同样的目的,通过名称来编写目录,但强制它不使用压缩。
if os.path.isdir(name): zf.write(name, arcname=arcname, compress_type=zipfile.ZIP_STORED) else: zf.write(name, arcname=arcname, compress_type=zipfile.ZIP_DEFLATED)
确保arcname
以/
结尾可能是值得的。
下面编辑的代码我跑了。 它基于上面的代码,取自邮件列表。 我添加了import,并做了一个主程序。 我也删除了输出文件名的摆弄,使代码更短。
#!/usr/bin/env python import os, zipfile, glob, sys def addFolderToZip(myZipFile,folder): folder = folder.encode('ascii') #convert path to ascii for ZipFile Method for file in glob.glob(folder+"/*"): if os.path.isfile(file): print file myZipFile.write(file, os.path.basename(file), zipfile.ZIP_DEFLATED) elif os.path.isdir(file): addFolderToZip(myZipFile,file) def createZipFile(filename,files,folders): myZipFile = zipfile.ZipFile( filename, "w" ) # Open the zip file for writing for file in files: file = file.encode('ascii') #convert path to ascii for ZipFile Method if os.path.isfile(file): (filepath, filename) = os.path.split(file) myZipFile.write( file, filename, zipfile.ZIP_DEFLATED ) for folder in folders: addFolderToZip(myZipFile,folder) myZipFile.close() return (1,filename) if __name__=="__main__": #put everything in sys.argv[1] in out.zip, skip files print createZipFile("out.zip", [], sys.argv[1])
在工作中,在我的Windows机器上,这段代码运行良好,但没有在zip文件中创build任何“文件夹”。 至less我记得它。 现在在家里,在我的Linux机器上,创build的zip文件似乎很糟糕:
$ unzip -l out.zip Archive: out.zip End-of-central-directory signature not found. Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive. unzip: cannot find zipfile directory in one of out.zip or out.zip.zip, and cannot find out.zip.ZIP, period.
我不知道如果我不小心破坏了代码,我认为它是一样的。 跨平台问题? 无论哪种方式,它与我原来的问题没有关系; 获取zip文件中的文件夹。 只是想发布我实际运行的代码,而不是基于代码的代码。
谢谢你这个有用的function! 我发现它非常有用,因为我也在寻求帮助。 不过,也许这样做会有所帮助
basedir = os.path.dirname(dirpath) + '/'
将会
basedir = os.path.dirname(dirpath + '/')
因为发现如果我想压缩位于'C:\ folder \ path \ notWanted \ to \ zip \ Example'的文件夹'Example',
我在Windows上:
dirpath = 'C:\folder\path\notWanted\to\zip\Example' basedir = 'C:\folder\path\notWanted\to\zip\Example/' dirname = 'C:\folder\path\notWanted\to\zip\Example\Example\Subfolder_etc'
但是我想你的代码应该给
dirpath = 'C:\folder\path\notWanted\to\zip\Example' basedir = 'C:\folder\path\notWanted\to\zip\Example\' dirname = '\Subfolder_etc'
import os import zipfile zf = zipfile.ZipFile("file.zip", "w") for file in os.listdir(os.curdir): if not file.endswith('.zip') and os.path.isfile(os.curdir+'/'+file): print file zf.write(file) elif os.path.isdir(os.curdir+'/'+file): print f for f in os.listdir(os.curdir+'/'+file): zf.write(file+'\\'+f) zf.close()
当你想创build一个空的文件夹,你可以这样做:
storage = api.Storage.open("empty_folder.zip","w") res = storage.open_resource("hannu//","w") storage.close()
文件夹不在winextractor中显示,但是当您提取它时显示。