zoukankan      html  css  js  c++  java
  • python打包压缩文件夹zip+组装文件夹

    无意间想到的一个需求,然后就顺手写了写,留下来,方便以后用

    列表版:(基本没用,仅提供思路,字典版稍微改动可以直接用)

      大体需求:

        把重复的文件名进行改名,达到浏览器下载相同文件的效果
        下载完成后再把文件夹和目录名删掉

    import os
    import zipfile
    import shutil
    import re
    
    
    def make_zip(source_dir, output_filename):
        zipf = zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED)
        pre_len = len(os.path.dirname(source_dir))
        for parent, dirnames, filenames in os.walk(source_dir):
            for filename in filenames:
                pathfile = os.path.join(parent, filename)
                arcname = pathfile[pre_len:].strip(os.path.sep)  # 相对路径
                zipf.write(pathfile, arcname)
        zipf.close()
    
    dir_name = "files"
    os.makedirs(dir_name)
    file_names = ["文件1","文件2","文件1","文件1","文件1","wenjian1"]
    file_names_sorted = sorted(file_names)
    file_new_names = []
    prog = re.compile(r".*((d+))$")
    for file_name in file_names_sorted:
        if file_name in file_new_names:
            if prog.match(file_new_names[-1]):
                file_name = file_name + "(%s)" % (int(prog.match(file_new_names[-1]).group(1))+1)
            else:
                file_name = file_name + "(1)"
        file_new_names.append(file_name)
    
    for file_new_name in file_new_names:
        file_path = os.path.join(dir_name, file_new_name)
        with open(file_path+'.py', mode="w", encoding="utf-8")as f:
            f.write("print('hello world!')")
    
    shutil.rmtree("files")
    os.remove("files")

    字典版:
      关键问题:tornado提供下载,对重复的文件名进行重命名(和浏览器类似)

    import os
    import zipfile
    import shutil
    import re
    import tornado.web
    
    
    class FileDownLoadHandler(tornado.web.RequestHandler):
        def post(self, *args, **kwargs):
            def make_zip(source_dir, output_filename):
                zipf = zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED)
                pre_len = len(os.path.dirname(source_dir))
                for parent, dirnames, filenames in os.walk(source_dir):
                    for filename in filenames:
                        pathfile = os.path.join(parent, filename)
                        arcname = pathfile[pre_len:].strip(os.path.sep)  # 相对路径
                        zipf.write(pathfile, arcname)
                zipf.close()
    
            # dir_name和file_infos都应该从数据库取
            dir_name = "新建文件夹"
            os.makedirs(dir_name)
            file_infos = [{'file_content': 'print("Hello World!")', 'file_name': '文件1'},
                          {'file_content': 'print("Hello World!")', 'file_name': '文件2'},
                          {'file_content': 'print("Hello World!")', 'file_name': '文件1'}]
            print(file_infos)
            file_infos_sorted = sorted(file_infos, key=lambda item: item["file_name"])
            prog = re.compile(r".*((d+))$")
            print(file_infos_sorted)
            file_new_infos = []
            file_names_set = set()
            for file_info in file_infos_sorted:
                if file_info["file_name"] in file_names_set:
                    if prog.match(file_new_infos[-1]["file_name"]):
                        file_info["file_name"] = file_info["file_name"] + "(%s)" % (
                            int(prog.match(file_new_infos[-1]["file_name"]).group(1)) + 1)
                    else:
                        file_info["file_name"] = file_info["file_name"] + "(1)"
                else:
                    file_names_set.add(file_info["file_name"])
                file_new_infos.append(file_info)
    
            for file_new_info in file_new_infos:
                file_path = os.path.join(dir_name, file_new_info["file_name"])
                with open(file_path + ".py", mode="w", encoding="utf-8")as f:
                    f.write(file_new_info["file_content"])
    
            target_name = dir_name + ".zip"
            make_zip(dir_name, target_name)  # 打包加压缩
    
            # 下载
            self.set_header('Content-Type', 'application/octet-stream')
            self.set_header('Content-Disposition', ('attachment; filename=%s' % target_name).encode("utf-8"))
            buf_size = 4096
            with open(target_name, "rb")as f:
                while True:
                    data = f.read(buf_size)
                    if not data:
                        break
                    self.write(data)
            self.finish()
    
            shutil.rmtree(dir_name)
            os.remove(target_name)

    才发现自己是真的菜,无意间问了一个java的同事,他们说Java可以直接写如zip流,然后找到了python的写入文件流的方式

    def test_zip(self):
        import zipfile, tempfile, os
        try:
            file_name = tempfile.mktemp(suffix=".zip")  # mktemp方法慎用
            with zipfile.ZipFile(file_name, 'w', zipfile.ZIP_DEFLATED) as zf:
                for i in range(5):
                    zf.writestr("文件名%s" % i, """print('文件内容')""")
                # 这里接着就是下载逻辑了,和上面的一样,就不重复写了
        finally:
            os.remove(file_name)
  • 相关阅读:
    WPF & DirectShow 相关资料
    Com开发之回调
    COM开发之结构体
    WPF 提供了以下关键帧动画类[msdn]
    COM数据类型与托管类型对照
    图文并茂 简单 ATL COM开发
    WPF 动画笔记
    ShaderEffect 相关资料
    Visual \UIElemnt\FrameworkElement\Control
    关于WPF装饰器的笔记
  • 原文地址:https://www.cnblogs.com/wuyongqiang/p/8717038.html
Copyright © 2011-2022 走看看