web-dev-qa-db-ja.com

zipファイルとディレクトリ構造の回避

Pythonスクリプトでファイルを圧縮します(new.txt)。

tofile =  "/root/files/result/"+file
targetzipfile = new.Zip   # This is how I want my Zip to look like
zf = zipfile.ZipFile(targetzipfile, mode='w')
try:
    #adding to archive
    zf.write(tofile)
finally:
    zf.close()

これを行うと、Zipファイルを取得します。しかし、ファイルを解凍しようとすると、ファイルのパスに対応する一連のディレクトリ内にテキストファイルが表示されます。つまり、rootディレクトリ内のresultというフォルダーと、その中のより多くのディレクトリが表示されます。

/root/files/result/new.Zip

そして私が解凍するとnew.Zip次のようなディレクトリ構造があります

/root/files/result/root/files/result/new.txt.

解凍するときにnew.txt

つまり、/root/files/result/new.Zipおよび解凍したときnew.Zip、次のようになります

/root/files/results/new.txt
27
user1189851

zipfile.write()メソッドは、オプションのarcname引数を使用して、zipファイル内のファイル名を指定します

宛先を変更する必要があると思います。そうしないと、ディレクトリが複製されます。 :arcnameを使用して回避してください。このようにしてみてください:

import os
import zipfile

def Zip(src, dst):
    zf = zipfile.ZipFile("%s.Zip" % (dst), "w", zipfile.Zip_DEFLATED)
    abs_src = os.path.abspath(src)
    for dirname, subdirs, files in os.walk(src):
        for filename in files:
            absname = os.path.abspath(os.path.join(dirname, filename))
            arcname = absname[len(abs_src) + 1:]
            print 'zipping %s as %s' % (os.path.join(dirname, filename),
                                        arcname)
            zf.write(absname, arcname)
    zf.close()

Zip("src", "dst")
40
user 12321
zf.write(tofile)

変える

zf.write(tofile, zipfile_dir)

例えば

zf.write("/root/files/result/root/files/result/new.txt", "/root/files/results/new.txt")
8
jinzy

最も明確に説明するために、

ディレクトリ構造:

/Users
 └── /user
 .    ├── /pixmaps
 .    │    ├── pixmap_00.raw
 .    │    ├── pixmap_01.raw
      │    ├── /jpeg
      │    │    ├── pixmap_00.jpg
      │    │    └── pixmap_01.jpg
      │    └── /png
      │         ├── pixmap_00.png
      │         └── pixmap_01.png
      ├── /docs
      ├── /programs
      ├── /misc
      .
      .
      .

関心のあるディレクトリ:/ Users/user/pixmaps

最初の試み

import os
import zipfile

TARGET_DIRECTORY = "/Users/user/pixmaps"
ZIPFILE_NAME = "CompressedDir.Zip"

def Zip_dir(directory, zipname):
    """
    Compress a directory (Zip file).
    """
    if os.path.exists(directory):
        outZipFile = zipfile.ZipFile(zipname, 'w', zipfile.Zip_DEFLATED)

        for dirpath, dirnames, filenames in os.walk(directory):
            for filename in filenames:

                filepath   = os.path.join(dirpath, filename)
                outZipFile.write(filepath)

        outZipFile.close()




if __name__ == '__main__':
    Zip_dir(TARGET_DIRECTORY, ZIPFILE_NAME)

Zipファイルの構造:

CompressedDir.Zip
.
└── /Users
     └── /user
          └── /pixmaps
               ├── pixmap_00.raw
               ├── pixmap_01.raw
               ├── /jpeg
               │    ├── pixmap_00.jpg
               │    └── pixmap_01.jpg
               └── /png
                    ├── pixmap_00.png
                    └── pixmap_01.png

完全なディレクトリパスを回避する

def Zip_dir(directory, zipname):
    """
    Compress a directory (Zip file).
    """
    if os.path.exists(directory):
        outZipFile = zipfile.ZipFile(zipname, 'w', zipfile.Zip_DEFLATED)

        # The root directory within the Zip file.
        rootdir = os.path.basename(directory)

        for dirpath, dirnames, filenames in os.walk(directory):
            for filename in filenames:

                # Write the file named filename to the archive,
                # giving it the archive name 'arcname'.
                filepath   = os.path.join(dirpath, filename)
                parentpath = os.path.relpath(filepath, directory)
                arcname    = os.path.join(rootdir, parentpath)

                outZipFile.write(filepath, arcname)

    outZipFile.close()




if __name__ == '__main__':
    Zip_dir(TARGET_DIRECTORY, ZIPFILE_NAME)

Zipファイルの構造:

CompressedDir.Zip
.
└── /pixmaps
     ├── pixmap_00.raw
     ├── pixmap_01.raw
     ├── /jpeg
     │    ├── pixmap_00.jpg
     │    └── pixmap_01.jpg
     └── /png
          ├── pixmap_00.png
          └── pixmap_01.png

以下を使用して、ソースファイルのファイル名のみを分離できます。

name_file_only= name_full_path.split(os.sep)[-1]

たとえば、name_full_path/root/files/results/myfile.txtの場合、name_file_onlymyfile.txtになります。 myfile.txtをアーカイブzfのルートに圧縮するには、次のコマンドを使用できます。

zf.write(name_full_path, name_file_only)
4

Zipfile.writeのドキュメントを確認してください。

ZipFile.write(filename [、arcname [、compress_type]])filenameという名前のファイルをアーカイブに書き込み、アーカイブ名をarcnameにします(デフォルトでは、これはfilenameと同じですが、ドライブ文字がなく、先行パスがあります)セパレーターは削除されました)

https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.write

以下を試してください:

import zipfile
import os
filename = 'foo.txt'

# Using os.path.join is better than using '/' it is OS agnostic
path = os.path.join(os.path.sep, 'tmp', 'bar', 'baz', filename)
Zip_filename = os.path.splitext(filename)[0] + '.Zip'
Zip_path = os.path.join(os.path.dirname(path), Zip_filename)

# If you need exception handling wrap this in a try/except block
with zipfile.ZipFile(Zip_path, 'w') as zf:
    zf.write(path, Zip_filename)

一番下の行は、アーカイブ名を指定しない場合、ファイル名がアーカイブ名として使用され、ファイルへの完全パスが含まれることです。

4
aquil.abdullah

私は同じ問題に直面し、writestrで解決します。次のように使用できます。

zipObject.writestr(<filename> , <file data, bytes or string>)

0
hubert