G W*_*ner 24 python directory zip shutil
我正在尝试将名为test_dicomszip文件的目录压缩为test_dicoms.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
Run Code Online (Sandbox Code Playgroud)
Rob*_*obᵩ 32
使用文档中的术语,您指定了root_dir,但未指定base_dir.尝试像这样指定base_dir:
shutil.make_archive('/home/code/test_dicoms',
'zip',
'/home/code/',
'test_dicoms')
Run Code Online (Sandbox Code Playgroud)
要回答第二个问题,这取决于您使用的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)
Run Code Online (Sandbox Code Playgroud)
参考:
我自己写了一个包装函数,因为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')
Run Code Online (Sandbox Code Playgroud)
我认为,我可以通过删除文件移动来改进 Seanbehan 的答案:
def make_archive(source, destination):
base_name = '.'.join(destination.split('.')[:-1])
format = destination.split('.')[-1]
root_dir = os.path.dirname(source)
base_dir = os.path.basename(source.strip(os.sep))
shutil.make_archive(base_name, format, root_dir, base_dir)
Run Code Online (Sandbox Code Playgroud)
基本上有两种使用方法shutil:您可以尝试理解其背后的逻辑,或者您可以只使用一个示例。我在这里找不到示例,所以我尝试创建自己的示例。
; 长话短说。运行shutil.make_archive('dir1_arc', 'zip', root_dir='dir1')或shutil.make_archive('dir1_arc', 'zip', base_dir='dir1')或 只是shutil.make_archive('dir1_arc', 'zip', 'dir1')从temp.
假设你有~/temp/dir1:
temp $ tree dir1\ndir1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dir11\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file11\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file12\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 file13\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dir1_arc.zip\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file2\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 file3\nRun Code Online (Sandbox Code Playgroud)\n如何创建 的档案dir1?放base_name='dir1_arc',format='zip'。好吧,你有很多 选择:
cd进入dir1并运行shutil.make_archive(base_name=base_name, format=format);它将dir1_arc.zip在里面创建一个档案dir1;唯一的问题是你会得到一个奇怪的行为:在你的档案中你会发现 file dir1_arc.zip;temp运行shutil.make_archive(base_name=base_name, format=format, base_dir='dir1');您将进入可以解压缩的dir1_arc.zip内部;默认为;tempdir1root_dirtemp~运行shutil.make_archive(base_name=base_name, format=format, root_dir='temp', base_dir='dir1');您将再次获得文件,但这次是在~目录内;temp2在~其中运行:shutil.make_archive(base_name=base_name, format=format, root_dir='../temp', base_dir='dir1'); 您将在此文件夹中找到您的存档temp2;您可以shutil在不指定参数的情况下运行吗?你可以。逃离temp shutil.make_archive('dir1_arc', 'zip', 'dir1')。这与运行相同shutil.make_archive('dir1_arc', 'zip', root_dir='dir1')。在这种情况下我们能说什么呢base_dir?从文档来看,没有那么多。从源码中我们可以看出:
if root_dir is not None:\n os.chdir(root_dir)\n\nif base_dir is None:\n base_dir = os.curdir \nRun Code Online (Sandbox Code Playgroud)\n所以在我们的例子中base_dir是dir1. 我们可以继续提问。