前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >遇到乱码问题,如何解决?

遇到乱码问题,如何解决?

作者头像
somenzz
发布2021-10-08 14:46:19
1.3K0
发布2021-10-08 14:46:19
举报
文章被收录于专栏:Python七号Python七号Python七号

完美的世界是没有乱码的,但是我们的世界是不完美的,乱码问题,你总有一天会遇到。

之前解决了一个 Python 的 UnicodeEncodeError 问题,比较具有代表性,特此分享一下,希望可以帮到遇到此类问题的朋友。

通常情况下,Linux 默认使用的字符编码是 utf-8,windows 是 gbk,不跨操作系统的情况下,我们按此编码存取数据,文件和文件名均不会出现乱码问题。

但现实就是要跨系统传输文件。如果文件名都是英文,也不会出现乱码问题,因为英文都是 ascii 编码,而所有的编码都是包含 ascii 码的,谁让人家先发明了计算机呢。

然而,现实就是需要跨系统传输中文名称的文件。

修改文件名的编码

乱码的原因就是编码不一样,比如说 Linux 一个中文名称的文件,“中文.txt",实际上保存在磁盘上时,对其做了 utf-8 的编码,实际保存的就是字节:"中文.txt".encode('utf-8'),这段字节传输到 Windows 机器上时不会改变,当你打开目录查看时,Windows 会按照 gbk 进行解码,就是 "中文.txt".encode('utf-8').decode('gbk'),编码和解码用到的字符集不一样,自然会乱码。

解决办法就是保存文件时,修改文件名的编码,怎么修改?

先来看下 Python 内建的 open 函数签名:

这里的 encoding 参数是指定文件内容的字符编码,而不是文件名的编码,因此我们需要关注 file 这个参数,file 是一个像路径一样的对象,点击 path-like object 可以看到说明:

也就是说,file 可以是一个字符串,也可以是字节串,那就好办了,假如要在 Linux 环境保存一个文件名是 gbk 编码的文件,可以这样做:

file_name = "中文.txt"

with open(file_name.encode('gbk'), "w",encoding = 'your file content encoding') as write:
    # do something

这个文件在 Linux 下的文件名看起来是乱码,但传输到 Windows 就是正常显示的。

ftplib 传输的编码问题

我在数仓做数据交换的时候,通常要 Linux 和 Windows 互相传文件,为此专门写过一个通用的传输文件库 transferfile[1],就遇到了两个编码问题:

1、Linux 向 Windows 传输的文件中文乱码。

解决方法:ftplib 考虑到了这一点,在 ftplib.FTP 初始化后可以传入 encoding 参数,来指定目标系统以何种编码保存文件名称。如下图所示:

2、Windows 下有乱码路径时无法在 Windows 里面递归的创建目标路径。

传输文件时可以指定目标路径,路径不存在时需要递归创建,以便存放上传的文件,ftplib 本身只能创建一个目录,需要自行写递归创建,那么创建之前就要先判断目录是否存在,这就需要用到 ftp.retrlines('LIST'),能列出来的就是存在的。

如果目录内没有乱码文件,也不会有问题,有就会报 UnicodeEncodeError,如下图:

怎么解决呢?

那就是不能让乱码目录影响了我们的主程序,在读取列表时遇到乱码忽略即可,按照 traceback 修改标准库 ftplib 文件 471 行,传入参数 errors='ignore' 如下图所示

标准库为什么不直接加上呢?我猜测就是为了让你知道,这里存在乱码,要忽略的话,自己搞定,我不为你背锅,😄。

最后

本文介绍了乱码问题的原因,如何修改文件名称的编码,用 ftplib 遇到的编码问题如何解决,虽然场景具体,但解决的乱码问题的思路都是一样的,那就是让编码解码使用的字符编码保持一致,如果乱码不影响可以忽略掉不能解码的数据。

如果想了解字符串编码的底层知识,推荐阅读前文Python 基础系列--字符串与编码 的第二节「二、字符串编码」

感谢阅读。又来求关注了,如果觉得内容还不错,请关注或在看分享给你的朋友们,感谢支持。

参考资料

[1]

transferfile: https://pypi.org/project/transferfile/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python七号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 修改文件名的编码
  • ftplib 传输的编码问题
  • 最后
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档