55

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ファイルに配置されます。フォルダ全体を追加することができませんでした。

myZipFile.write内のフォルダーへのパスをフィードすると、次のようになります。

IOError:[Errno 13]アクセスが拒否されました:'.. \ packed \ bin'

どんな助けでも大歓迎です。

関連する質問:Python(バージョン2.5)を使用してフォルダーの内容を圧縮するにはどうすればよいですか?

4

13 に答える 13

66

また、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形式で保存されます。

于 2011-06-28T19:05:19.627 に答える
53

わかりました、あなたが何を望んでいるかを理解した後、それは の 2 番目の引数を使用するのと同じくらい簡単ですzipfile.write。ここでは、必要なものを何でも使用できます。

import zipfile
myZipFile = zipfile.ZipFile("zip.zip", "w" )
myZipFile.write("test.py", "dir\\test.py", zipfile.ZIP_DEFLATED )

test.pyと呼ばれるディレクトリに抽出されるzipファイルを作成しますdir

編集:私はかつてzipファイルに空のディレクトリを作成しなければなりませんでした:それは可能です. 上記のコードがファイル test.py を zipfile から削除した後、ファイルはなくなりますが、空のディレクトリは残ります。

于 2009-01-19T22:21:46.883 に答える
16

zip ファイルにはディレクトリ構造がなく、一連のパス名とその内容が含まれているだけです。これらのパス名は、架空のルート フォルダー (ZIP ファイル自体) に関連している必要があります。"../" プレフィックスは、zip ファイルでは定義された意味を持ちません。

ファイルがあり、aそれを zip ファイル内の「フォルダー」に保存したいとします。ファイルをzipファイルに保存するときに、ファイル名の前にフォルダー名を付けるだけです。

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 実装を知りません。回避策を考えることはできますが(抽出時に無視する必要があるダミーのファイル名をzip「フォルダー」に保存する)、実装間で移植することはできません。

于 2009-01-19T21:34:13.453 に答える
11
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)

ご覧のとおり、動作し、アーカイブも問題ありません。これは、フォルダ全体を圧縮できる再帰関数です。唯一の問題は、空のフォルダが作成されないことです。

乾杯。

于 2009-03-22T07:03:11.440 に答える
4

以下は、ディレクトリ全体を zip ファイルに圧縮するためのコードです。

これは、Windows と Linux の両方で zip ファイルを作成するのに問題ないようです。出力ファイルは、Windows (組み込みの圧縮フォルダー機能、WinZip、および 7-Zip) および Linux で適切に抽出されるようです。ただし、zip ファイル内の空のディレクトリは厄介な問題のようです。以下の解決策は機能しているように見えますが、Linux での「zipinfo」の出力に問題があります。また、zip アーカイブ内の空のディレクトリに対して、ディレクトリのアクセス許可が正しく設定されていません。これには、さらに詳細な調査が必要なようです。

このベロシティ レビュー スレッドこの python メーリング リスト スレッドから情報を得ました。

この関数は、親ディレクトリがないか、親ディレクトリが 1 つだけの zip アーカイブにファイルを配置するように設計されているため、ファイルシステム パスの先頭のディレクトリは削除され、zip アーカイブ パスには含まれません。これは通常、ディレクトリを取得して、別の場所に展開できる zip ファイルに変換したい場合に当てはまります。

キーワード引数:

dirPath -- アーカイブするディレクトリへの文字列パス。必須の引数はこれだけです。絶対ディレクトリまたは相対ディレクトリにすることができますが、zip アーカイブには 1 つまたはゼロの先行ディレクトリのみが含まれます。

zipFilePath -- 出力 zip ファイルへの文字列パス。これは、絶対パスまたは相対パスにすることができます。zip ファイルが既に存在する場合は、更新されます。そうでない場合は作成されます。最初から置き換えたい場合は、この関数を呼び出す前に削除してください。(デフォルトは dirPath + ".zip" として計算されます)

includeDirInZip -- 最上位ディレクトリをアーカイブに含めるか省略するかを示すブール値。(デフォルトは真)

(StackOverflow は、私の python を三重引用符で囲まれた文字列できれいに印刷できないようです。そのため、doc 文字列をここの投稿テキストに変換しただけです)

#!/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")
于 2009-04-27T03:53:45.827 に答える
3

フォルダーを圧縮するために使用する関数は次のとおりです。

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()
于 2009-10-09T17:04:44.070 に答える
2

いくつかのインポートを追加した後、コードは問題なく実行されます。スクリプトをどのように呼び出すのですか?「..\packed\bin」ディレクトリのフォルダー構造を教えてください。

次の引数を使用してコードを呼び出しました。

planName='test.zip'
files=['z.py',]
folders=['c:\\temp']
(success,filename)=createZipFile(planName,files,folders)

`

于 2009-01-19T17:47:34.503 に答える
0

便利な機能をありがとうございます!私もヘルプを探していたので、とても役に立ちました。ただし、少し変更すると役立つ場合があります。

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'
于 2009-12-15T10:17:30.763 に答える
0
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()
于 2014-09-17T19:32:24.997 に答える
0

Heres私が実行した編集されたコードです。メーリングリストから取得した上記のコードに基づいています。インポートを追加し、メインルーチンを作成しました。また、コードを短くするために、出力ファイル名をいじる必要もありません。

#!/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 ファイルに「フォルダー」は作成されませんでした。少なくとも私はそうだったことを覚えています。現在、自宅の Linux ボックスで、作成された 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 ファイル内のフォルダーを取得します。コードの基になったコードではなく、実際に実行したコードを投稿したかっただけです。

于 2009-01-19T22:26:04.097 に答える
-3

空のフォルダーを作成する場合は、次のようにします。

    storage = api.Storage.open("empty_folder.zip","w")
    res = storage.open_resource("hannu//","w")
    storage.close()

フォルダはwineextractorには表示されませんが、抽出すると表示されます。

于 2009-03-24T08:06:09.293 に答える