使用python将文件夹添加到zip文件

Miz*_*zor 45 python directory zip file zipfile

我想创建一个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);
Run Code Online (Sandbox Code Playgroud)

摘自:http://mail.python.org/pipermail/python-list/2006-August/396166.html

删除所有文件夹并将目标文件夹(及其子文件夹)中的所有文件放入单个zip文件中.我无法让它添加整个文件夹.

如果我将路径提供给myZipFile.write中的文件夹,我会得到

IOError:[Errno 13]权限被拒绝:'..\packed\bin'

任何帮助都非常受欢迎.

相关问题:如何使用python(2.5版)压缩文件夹的内容?

Gid*_*eon 57

你也可以使用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)
Run Code Online (Sandbox Code Playgroud)

这会将整个文件夹放在zip中.

  • 它仅适用于Python 2.7+ (5认同)
  • 它不保留符号链接 (2认同)

RSa*_*bet 48

好吧,在我明白你想要的东西之后,它就像使用第二个参数一样简单zipfile.write,你可以使用你想要的任何东西:

import zipfile
myZipFile = zipfile.ZipFile("zip.zip", "w" )
myZipFile.write("test.py", "dir\\test.py", zipfile.ZIP_DEFLATED )
Run Code Online (Sandbox Code Playgroud)

创建一个zipfile文件,test.py将其解压缩到一个名为的目录dir

编辑:我曾经不得不在zip文件中创建一个空目录:这是可能的.在上面的代码刚刚从zipfile中删除文件test.py之后,文件就消失了,但是空目录仍然存在.

  • 为了使它跨平台工作,您需要使用os.path.join(“ dir”,“ test.py”) (3认同)

tzo*_*zot 14

zip文件没有目录结构,只有一堆路径名及其内容.这些路径名应该相对于一个虚构的根文件夹(ZIP文件本身)."../"前缀在zip文件中没有定义的含义.

假设您有一个文件,a并且您希望将其存储在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
Run Code Online (Sandbox Code Playgroud)

我不知道任何ZIP实现允许在ZIP文件中包含文件夹.我可以想到一个解决方法(在zip"文件夹"中存储虚拟文件名,在提取时应该忽略),但不能跨实现移植.

  • 我知道了.所以如果我说得对,zip文件不包含任何文件夹.但是,如果文件的名称中有一个路径分隔符,它在大多数归档管理器的文件夹中显示为文件?在解压缩存档时会以这种方式创建吗? (2认同)

小智 8

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()
Run Code Online (Sandbox Code Playgroud)

我在跑:

python tozip.py
Run Code Online (Sandbox Code Playgroud)

这是日志:

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)
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它可以工作,存档也可以.这是一个递归函数,可以压缩整个文件夹.唯一的问题是它不会创建一个空文件夹.

干杯.


小智 5

下面是一些将整个目录压缩到 zip 文件中的代码。

这似乎可以在 Windows 和 Linux 上创建 zip 文件。输出文件似乎可以在 Windows(内置压缩文件夹功能、WinZip 和 7-Zip)和 Linux 上正确提取。然而,zip 文件中的空目录似乎是一个棘手的问题。下面的解决方案似乎有效,但 Linux 上“zipinfo”的输出令人担忧。此外,zip 存档中的空目录的目录权限设置不正确。这似乎需要更深入的研究。

我从这个速度评论线程这个 python 邮件列表线程中得到了一些信息。

请注意,此函数旨在将文件放入没有父目录或只有一个父目录的 zip 存档中,因此它将修剪文件系统路径中的任何前导目录,而不将它们包含在 zip 存档路径中。当您只想获取一个目录并将其制作成可以在不同位置提取的 zip 文件时,通常会出现这种情况。

关键字参数:

dirPath——要归档的目录的字符串路径。这是唯一必需的参数。它可以是绝对的或相对的,但 zip 存档中只会包含一个或零个前导目录。

zipFilePath -- 输出 zip 文件的字符串路径。这可以是绝对路径或相对路径。如果 zip 文件已存在,则会更新该文件。如果没有,它将被创建。如果您想从头开始替换它,请在调用此函数之前将其删除。(默认计算为 dirPath + ".zip")

includeDirInZip —— 布尔值,指示顶级目录是否应包含在存档中或省略。(默认为真)

(请注意,StackOverflow 似乎无法用三重引号字符串漂亮地打印我的 python,因此我只是将我的文档字符串转换为此处的帖子文本)

#!/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()
Run Code Online (Sandbox Code Playgroud)

这是一些示例用法。请注意,如果您的 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")
Run Code Online (Sandbox Code Playgroud)