zipfile 解压文件名 中文字符 乱码

unzip 中文文件名乱码

上传文件功能模块需求及BUG现象:

上传一个.zip格式的压缩文件

解压该test.zip压缩文件

解压zip文件时,遍历其目录下所有子文件,同时计算出单个子文件的有效代码行数

这时,发现解压后的子文件名中文出现乱码,如下图:

BUG截图

解决思路

1、解压过程中,发现解压的文件内容正常;

2、使用的是第三方库zipfile模块,因为第1步得到正常的文件内容,本地业务逻辑可先不排查;

3、首先检查zipfile的源码中,针对编码/解码的执行过程仔细排查发现:

zipfile中根据文件 flag 检测的时候,只支持 cp437 和 utf-8

找到下面两处,并追加修正后,乱码现象解决:(追加的decode编码可根据实际情况修改,如linux环境下乱码采用.decode(‘gbk‘))

# zipfile.py

# 第一处
if flags & 0x800:
    # UTF-8 file names extension
    filename = filename.decode(‘utf-8‘)
else:
    # Historical ZIP filename encoding
    filename = filename.decode(‘cp437‘)
    # 追加此句
    filename = filename.encode("cp437").decode(‘utf-8‘)

# 第二处
if zinfo.flag_bits & 0x800:
    # UTF-8 filename
    fname_str = fname.decode("utf-8")
else:
    fname_str = fname.decode("cp437")
        # 追加此句
    fname_str = fname_str.encode("cp437").decode(‘utf-8‘)

解决后,正常显示:


上床功能源码

import zipfile

# 定义全局变量,存储上传解压后的文件列表
filelists = []
# 指定想要统计的文件类型
whitelist = [‘py‘]

# 遍历文件, 递归遍历文件夹中的所有
def getFile(basedir):
    global filelists
    for parent, dirnames, filenames in os.walk(basedir):
        # for dirname in dirnames:
        #    getFile(os.path.join(parent,dirname)) #递归
        for filename in filenames:
            ext = filename.split(‘.‘)[-1]
            # 只统计指定的文件类型,略过一些log和cache文件
            if ext in whitelist:
                filelists.append(os.path.join(parent, filename))

# 统计一个文件的行数
def countLine(fname):
    count = 0
    single_quotes_flag = False
    double_quotes_flag = False
    with open(fname, ‘rb‘) as f:
        for file_line in f:
            file_line = file_line.strip()
            # print(file_line)
            # 空行
            if file_line == b‘‘:
                pass

            # 注释 # 开头
            elif file_line.startswith(b‘#‘):
                pass

            # 注释 单引号 ‘‘‘ 开头
            elif file_line.startswith(b"‘‘‘") and not single_quotes_flag:
                single_quotes_flag = True
            # 注释 中间 和 ‘‘‘ 结尾
            elif single_quotes_flag == True:
                if file_line.endswith(b"‘‘‘"):
                    single_quotes_flag = False

            # 注释 双引号 """ 开头
            elif file_line.startswith(b‘"""‘) and not double_quotes_flag:
                double_quotes_flag = True
            # 注释 中间 和 """  结尾
            elif double_quotes_flag == True:
                if (file_line.endswith(b‘"""‘)):
                    double_quotes_flag = False

            # 代码
            else:
                count += 1

        # print(fname + ‘----‘, count)
        #   单个文件行数
        print(fname, ‘----count:‘, count)
        return count

def un_zip(file_name):
    """unzip zip file"""
    zip_file = zipfile.ZipFile(file_name)
    # <zipfile.ZipFile filename=‘/Users/limengjie/Desktop/pyhon/SMS0614/upload_file/0617.zip‘ mode=‘r‘>
    if os.path.isdir(file_name + "_files"):
        pass
    else:
        os.mkdir(file_name + "_files")
    for names in zip_file.namelist():
        zip_file.extract(names, file_name + "_files/")
    # 遍历解压后得到的文件夹, 递归遍历文件夹中的所有子文件
    getFile(file_name + "_files")
    totalline = 0
    # 遍历解压后的文件列表,统计单个文件的行数并汇总
    for filelist in filelists:
        totalline = totalline + countLine(filelist)
    zip_file.close()
    # 返回上传文件所有子文件的总行数
    return totalline

补充:上传业务逻辑代码

class Uploading(View):

    def get(self, request):
        return render(request, "uploading.html", )

    def post(self, request):
        # 1、拿到压缩文件对象file_obj
        file_obj = request.FILES.get("user_file")
        file_name = os.path.join(file_dir, file_obj.name)
        file_size = file_obj.size
        with open(file_name, "wb") as f:
            for line in file_obj.chunks():
                f.write(line)

        # 2、解压压缩文件,并获取代码行数属性
        total_line = un_zip(file_name)
        # 3、单个文件进行文件对象实例化,文件名,文件大小,代码行数
        models.FileObj.objects.create(
            fileName=file_obj.name,
            fileSize=file_size,
            fileLineCount=total_line
        )
        return redirect("/upload_file/")

(完)

原文地址:https://www.cnblogs.com/limengjie0104/p/9192449.html

时间: 2024-10-04 20:09:01

zipfile 解压文件名 中文字符 乱码的相关文章

iOS 文件下载 (AFNetwork 三方框架 文件名中文字符乱码问题解决)四

很久以前,就把这篇文章的andriod部分和服务器部分搞定,最近论文送审途中,于是写了几行简单的代码如下. 把AFNetwork拿来做一下.具体代码如下: -(void)download { NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] i

ubuntu下解压zip rar中文字符乱码的问题

如题,解压zip rar中文乱码的问i题一直困扰着我,每次都要到window系统下解压,很是不方便,今天终于把这类问题解决了.整理总结分享如下 一 .    解决 Rar 压缩文件乱码问题 Rar 压缩在 Ubuntu 下可能出现乱码,这是由于安装了 rar 软件包(开源 Rar 压缩格式解压工具), 解决方法是安装闭源的 unrar 软件包,在终端依次输入以下命令即可: sudo apt-get remove rar sudo apt-get install p7zip-full p7zip-

在linux下解决默认解压zip中文乱码问题

在linux下直接unzip xx.zip 时,总会遇到乱码问题,这是因为在windows上压缩的文件,是以windows默认编码中文来压缩文件.由于zip文件中没有声明其编码,所以linux上的unzip一般以默认编码解压,中文文件名会出现乱码. 解决的方法是: 1.解压时指定编码: unzip -O CP936 xx.zip 2.在环境变量中,指定unzip参数,总是以指定的字符集显示和解压文件 /etc/environment中加入2行: UNZIP="-O CP936" ZIP

解决ubuntu中zip解压的中文乱码问题

在解压windows传过来的zip文件时,才会出现乱码.所以,我用另一个方法解决中文乱码问题. 安装 代码: sudo apt-get install unar 12.04以下或者想编译安装的朋友请参考: 使用 代码: lsar foo.zip #列出所有文件 如果列出的文件名已经正确 代码: unar foo.zip #解压所有文件 如果列出的文件名还不正确 代码: lsar -e GB18030 foo.zip #指定使用GB18030编码列出所有文件 unar -e GB18030 foo

mysql中采用concat来拼接中文字符乱码解决方式(转)

mysql中采用concat来拼接中文字符乱码解决方式 - fuxuejun的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/fuxuejun/article/details/6284725 mysql concat乱码问题解决 concat(str1,str2) 当concat结果集出现乱码时,大都是由于连接的字段类型不同导致,如concat中的字段参数一个是varchar类型,一个是int类型或doule类型,就会出现乱码. 解决方法:利用mysql的字符

Keil uVision4 代码编辑器中文字符乱码问题

MDK-ARM 使用中一直有个很纠结的问题,中文字符支持不好. 比如写代码注释,使用中文删除字符就会只删除一半问题.复制粘贴代码中间有中文就会出现乱码问题. 想过换IAR,新学个IDE也麻烦,上面的问题也不很大稍微绕一下也能解决,所以一直没换. 发现其实这个根本不是问题,安装好后默认是ANSI编码,所以会出现上述问题.只要把编码改成UTF-8编码就能解决上述烦恼. 设置步骤:     1.选择菜单:[Edit]->[Configuration]       2.页签[Editor]中 Gener

SpringMVC项目中中文字符乱码问题及解决办法总结(非专业最优解决办法) -- ajax传值乱码; request.getParameter()乱码;

情况一: ajax中传值时是乱码(后台可以获取到中文字符,但用@ResponseBody返回时前台为乱码) 情况二: Controller 中 request.getParameter()获取到的是乱码 @RequestMapping(params = "method=submit") public String submit(HttpServletRequest request, ModelMap modelMap) throws Exception{ String uname =

jsp与mysql中的中文字符乱码问题

刚开始自学jsp,在练习的过程中遇到了一个很严重的问题,就是中文字符乱码的问题,我用了三天的时间,搜集资料,终于解决了这个问题,现在对学到的东西进行一下总结整理. 1.首先是jsp页面显示乱码的问题,<title></title>标签中有中文有英文,设置<meta charset="utf-8" > 显示乱码,改为gbk则可正常显示,其他页面使用utf-8则显示正常.最终发现是因为文件创建是用了不同的方法,一般情况下,用记事本编写代码,文件另存为*.

笔记:PHP查询mysql数据后中文字符乱码

新建表Clubs CREATE TABLE `Clubs` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; id name 1 程序员2 架构师3 产品经