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
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")
zf.write(tofile)
変える
zf.write(tofile, zipfile_dir)
例えば
zf.write("/root/files/result/root/files/result/new.txt", "/root/files/results/new.txt")
最も明確に説明するために、
ディレクトリ構造:
/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_only
はmyfile.txt
になります。 myfile.txtをアーカイブzf
のルートに圧縮するには、次のコマンドを使用できます。
zf.write(name_full_path, name_file_only)
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)
一番下の行は、アーカイブ名を指定しない場合、ファイル名がアーカイブ名として使用され、ファイルへの完全パスが含まれることです。
私は同じ問題に直面し、writestr
で解決します。次のように使用できます。
zipObject.writestr(<filename> , <file data, bytes or string>)