Python版本:2.7.6
zipfile库参考资料:https://docs.python.org/2/library/zipfile.html
首先,要压缩一个文件到一个zip文件里是很简单的,上面参考资料里已经有代码了:
with ZipFile('spam.zip', 'w') as myzip: myzip.write('eggs.txt') |
这样就可以把eggs.txt压缩成spam.zip了。
但这样默认没有对文件进行压缩,所以创建zip文件时要设置一下参数:
with ZipFile('spam.zip', 'w', ZIP_DEFLATED) as myzip: myzip.write('eggs.txt') |
多数情况下,我们需要压缩的是一个目录下的很多文件,所以我们要把文件枚举出来,然后打到包里去。
首先定义一个枚举文件的函数:
def get_items_list_in_dir(src, lst): for item in os.listdir(src): path = os.path.join(src, item) lst.append(path) if os.path.isdir(path): get_items_list_in_dir(path, lst) |
调用上面的函数获得文件列表后,全部打到zip包中:
itemList = [] itemList.append("input_dir") get_items_list_in_dir("input_dir", itemList) with ZipFile("out.zip", 'w', ZIP_DEFLATED) as myzip: for item in itemList: myzip.write(item) |
以上就实现了把input_dir整个目录压缩打包成out.zip的功能。
这样已经可以实现多数的需求了。不过偶尔有需求在打包时将文件改名,比如,希望打包时将input_dir这个文件夹的名字改成output_dir,可以这样做一下改进:
itemList = [] itemList.append("input_dir") get_items_list_in_dir("input_dir", itemList) with ZipFile("out.zip", 'w', ZIP_DEFLATED) as myzip: for item in itemList: new_item = item.replace("input_dir", "output_dir") myzip.write(item, new_item) |
以上已经基本实现了完整的打包功能。但在实际使用中,我们通常会将要打包的目录、输出的文件等作为参数从命令行传入,所以我们还要引进OptionParser来解析参数。
最后的实现文件如下:
#!/usr/bin/python # coding=utf-8 import os from optparse import OptionParser from zipfile import * def get_items_list_in_dir(src, lst): for item in os.listdir(src): path = os.path.join(src, item) lst.append(path) if os.path.isdir(path): get_items_list_in_dir(path, lst) if __name__ == '__main__': parser = OptionParser() parser.add_option( '-i', '--input', dest='dir_input', help='directory of input files') parser.add_option( '-o', '--output', dest='file_output', help='output file name') parser.add_option( '-n', '--new_dir', dest='dir_new', help='new dir name') opts, args = parser.parse_args() if opts.dir_input is None: print 'Please set input directory: use -i <dir>' exit() if opts.file_output is None: print 'Please set output filename: use -o <filename>' exit() dir_input = opts.dir_input file_output = opts.file_output dir_new = opts.dir_new itemList = [] itemList.append(dir_input) get_items_list_in_dir(dir_input, itemList) with ZipFile(file_output, 'w', ZIP_DEFLATED) as myzip: for item in itemList: if dir_new: new_item = item.replace(dir_input, dir_new) else: new_item = item print "%s ==> %s" % (item, new_item) myzip.write(item, new_item) |