我有一个程序来压缩文件夹中的所有内容。我没有写这个代码,但我发现它在网上某处,我正在使用它。我打算压缩一个文件夹,比如说C:/ folder1 / folder2 / folder3 /。我想将folder3及其所有内容压缩到一个文件中说folder3.zip。使用下面的代码,一旦我压缩它,folder3.zip的内容将是folder1 / folder2 / folder3 /和files。我不希望整个路径被压缩,我只想让我感兴趣的子文件夹zip(在这种情况下为folder3)。我尝试了一些os.chdir等,但没有运气。
def makeArchive(fileList, archive):
"""
'fileList' is a list of file names - full path each name
'archive' is the file name for the archive with a full path
"""
try:
a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)
for f in fileList:
print "archiving file %s" % (f)
a.write(f)
a.close()
return True
except: return False
def dirEntries(dir_name, subdir, *args):
# Creates a list of all files in the folder
'''Return a list of file names found in directory 'dir_name'
If 'subdir' is True, recursively access subdirectories under 'dir_name'.
Additional arguments, if any, are file extensions to match filenames. Matched
file names are added to the list.
If there are no additional arguments, all files found in the directory are
added to the list.
Example usage: fileList = dirEntries(r'H:\TEMP', False, 'txt', 'py')
Only files with 'txt' and 'py' extensions will be added to the list.
Example usage: fileList = dirEntries(r'H:\TEMP', True)
All files and all the files in subdirectories under H:\TEMP will be added
to the list. '''
fileList = []
for file in os.listdir(dir_name):
dirfile = os.path.join(dir_name, file)
if os.path.isfile(dirfile):
if not args:
fileList.append(dirfile)
else:
if os.path.splitext(dirfile)[1][1:] in args:
fileList.append(dirfile)
# recursively access file names in subdirectories
elif os.path.isdir(dirfile) and subdir:
print "Accessing directory:", dirfile
fileList.extend(dirEntries(dirfile, subdir, *args))
return fileList
您可以通过makeArchive(dirEntries(folder, True), zipname)
拨打此电话。
关于如何解决这个问题的任何想法?我正在使用Windows操作系统和python 25,我知道在python 2.7中有shutil make_archive这有帮助但是因为我正在使用2.5我需要另一个解决方案: - /
答案 0 :(得分:17)
您必须向使用相对路径的ZipFile.write()
提供arcname
参数。通过将根路径移除到makeArchive()
来执行此操作:
def makeArchive(fileList, archive, root):
"""
'fileList' is a list of file names - full path each name
'archive' is the file name for the archive with a full path
"""
a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)
for f in fileList:
print "archiving file %s" % (f)
a.write(f, os.path.relpath(f, root))
a.close()
并将其称为:
makeArchive(dirEntries(folder, True), zipname, folder)
我已删除了try:
,except:
;这里没有用处,只能隐藏你想知道的问题。
os.path.relpath()
函数返回相对于root
的路径,有效地从归档条目中删除该根路径。
在python 2.5上,relpath
函数不可用;对于此特定用例,以下替换将起作用:
def relpath(filename, root):
return filename[len(root):].lstrip(os.path.sep).lstrip(os.path.altsep)
并使用:
a.write(f, relpath(f, root))
请注意,上述relpath()
功能仅适用于filepath
保证以root
开头的特定情况;在Windows上,relpath()
的一般情况要复杂得多。你真的想要尽可能升级到Python 2.6或更高版本。
答案 1 :(得分:2)
ZipFile.write有一个可选参数arcname
。用它来删除部分路径。
您可以将方法更改为:
def makeArchive(fileList, archive, path_prefix=None):
"""
'fileList' is a list of file names - full path each name
'archive' is the file name for the archive with a full path
"""
try:
a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)
for f in fileList:
print "archiving file %s" % (f)
if path_prefix is None:
a.write(f)
else:
a.write(f, f[len(path_prefix):] if f.startswith(path_prefix) else f)
a.close()
return True
except: return False
Martijn使用os.path的方法更加优雅。