次のコードを使用して、test_dicoms
というディレクトリをtest_dicoms.Zip
という名前のZipファイルにZipしようとしています。
shutil.make_archive('/home/code/test_dicoms','Zip','/home/code/test_dicoms')
問題は、解凍すると、/test_dicoms/
にあったすべてのファイルが、フォルダー/home/code/
ではなく/test_dicoms/
に抽出され、すべてのファイルに/home/code/
に抽出されるファイルが含まれることです。したがって、/test_dicoms/
にはfoo.txt
というファイルがあり、foo.txt
ではなく/home/code/foo.txt
のパスを/home/code/test_dicoms/foo.txt
に圧縮して解凍します。どうすれば修正できますか?また、私が作業しているディレクトリのいくつかは非常に大きいです。 Zip64にするためにコードに何かを追加する必要がありますか、それとも自動的にそれを行うのに十分な機能ですか
現在作成されているアーカイブには次のものがあります。
[gwarner@jazz gwarner]$ unzip -l test_dicoms.Zip
Archive: test_dicoms.Zip
Length Date Time Name
--------- ---------- ----- ----
93324 09-17-2015 16:05 AAscout_b_000070
93332 09-17-2015 16:05 AAscout_b_000125
93332 09-17-2015 16:05 AAscout_b_000248
ドキュメントの用語を使用して、root_dirを指定しましたが、base_dir。次のようにbase_dirを指定してみてください:
_shutil.make_archive('/home/code/test_dicoms',
'Zip',
'/home/code/',
'test_dicoms')
_
2番目の質問に答えるには、使用しているPythonのバージョンに依存します。Python 3.4から、Zip64拡張機能はデフォルトで利用可能になります。 Python 3.4、_make_archive
_は自動的にZip64拡張子のファイルを作成しません。古いバージョンのPythonを使用していてZip64が必要な場合は、基になるzipfile.ZipFile()
を直接呼び出すことができます。
zipfile.ZipFile()
をバイパスして、shutil.make_archive()
を直接使用することを選択した場合の例を次に示します。
_import zipfile
import os
d = '/home/code/test_dicoms'
os.chdir(os.path.dirname(d))
with zipfile.ZipFile(d + '.Zip',
"w",
zipfile.Zip_DEFLATED,
allowZip64=True) as zf:
for root, _, filenames in os.walk(os.path.basename(d)):
for name in filenames:
name = os.path.join(root, name)
name = os.path.normpath(name)
zf.write(name, name)
_
参照:
Shutil.make_archiveを使用するのはわかりにくいため、自分でラッパー関数を作成しました。
そして、ただのコード..
import os, shutil
def make_archive(source, destination):
base = os.path.basename(destination)
name = base.split('.')[0]
format = base.split('.')[1]
archive_from = os.path.dirname(source)
archive_to = os.path.basename(source.strip(os.sep))
shutil.make_archive(name, format, archive_from, archive_to)
shutil.move('%s.%s'%(name,format), destination)
make_archive('/path/to/folder', '/path/to/folder.Zip')