博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有关linux与windows中文件名的编码问题总结
阅读量:6972 次
发布时间:2019-06-27

本文共 2217 字,大约阅读时间需要 7 分钟。

hot3.png

最近在整理各种裤子,由于太大用了ntfs-3g挂载硬盘,拷贝到了centos服务器上,结果没有注意文件名的编码问题,总要修改所以说config/i18n配置文件,而且通过ssh连接要经常切换客户端的字符集,无奈,拷回硬盘上,在window上弄吧,结果,文件名出现各种乱码。。。。崩溃了。安心学习了。。。

(其中涉及到了ntfs-3g,ssh远程客户端,以及linux的/etc/sysconfig/i18n配置,没有一一测试,除了ntfs-3g不知道是否涉及字符集,其他都涉及到了,思路比较乱,想到哪写到哪了)

问题根源:由于Linux与windows采用了不同的字符集来处理中文文件名,Linux用了utf-8而windows用了gbk,进而导致文件名处理的混乱。

我的做法是:

1、利用convmv 在linux上将所有文件名编码转换为gbk,再通过ntfs-3g将文件拷到移动硬盘,最后拷回电脑,在windows上能够正常显示。

2、处理文件

3、将文件拷回linux

4、利用convmv将文件名转回utf8

由于习惯了在windows上开发, 想自己写一个py脚本实现在windows上将文件名字符编码进行转换的功能,但是马上问题就出现了。

下面请看:

def conv_gbk_to_utf8(path):    if os.path.exists(path):        print 'converting filename to utf8...'    else:        print 'The path is invalid!'        return -1    for root, dirs, files in os.walk(path):        for filename in files:            charset = chardet.detect(filename)            if charset.get('encoding') in ['utf-8', 'ascii']:                continue            else:                print charset                conv_filename = filename.decode('gbk').encode()                res_filename = os.path.join(root, filename)                conv_filename = os.path.join(root, conv_filename)                shutil.move(res_filename, conv_filename)    # modified the charset of name of the dirs    for root, dirs, files in os.walk(path):        for dir in dirs:            charset = chardet.detect(dir)            if charset.get('encoding') in ['utf-8', 'ascii']:                continue            else:                conv_dir = dir.decode('gb2312').encode()                res_dir = os.path.join(root, dir)                conv_dir = os.path.join(root, conv_dir)                print res_dir, conv_dir                shutil.move(res_dir, conv_dir)

对于一般的文件名都没问题,但是由于windows对文件命名有着一个限制。就是 ? : " < > 等符号无法被作为合法字符。

那么当一个名为 新建文件夹 的文件夹 ,将字符集从gbk转换为utf8之后,会显示为:鏂板缓鏂囦欢澶, 其编码为:E6 96 B0 E5 BB BA E6 96 87 E4 BB B6 E5 A4 B9 ,如果用编辑工具转换发现实际转换后的字符应该是鏂板缓鏂囦欢澶? B9被丢弃了。

结论:在用程序转换后,出现的特殊字符,会被操作系统丢弃,因而也无法复原。所以这种方法,目前走不通。。。也隐约证明了,为什么之前在网上搜索文件名编码转换工具都找不到了吧。。。。

ps:回去又研究了下,shutil.move的实现方法是对文件直接调用os.rename对文件夹采用copytree和rmtree来实现重命名目录的。在copytree中调用了

os.makedirs(dst)

然后调用了nt.py中的

mkdir(name, mode)

 

这步是有c实现的底层库,而在这步就会产生丢字节B9的现象,因此如果想实现此功能需要修改底层实现。 

转载于:https://my.oschina.net/u/2269890/blog/492487

你可能感兴趣的文章
LeetCode第七天
查看>>
java中json的使用和解析
查看>>
C语言面试笔试整理笔记(二)
查看>>
Hibernate 5.x 配置 C3P0 数据库连接池
查看>>
自测是保证开发提交代码质量的最基本方法和最低要求
查看>>
Java_myeclipse添加DTD约束(框架xml只能提示功能)
查看>>
CSS3基础知识学习
查看>>
eclipse 创建普通maven项目
查看>>
vue webpack build 打包过滤console.log()日志
查看>>
iOS — Autolayout之Masonry解读
查看>>
ORACLE存储过程 练习系列三 失效或者生效指定表的外键
查看>>
用户表空间查询
查看>>
求整数数组中最大子数组的和
查看>>
hdu2546-饭卡???
查看>>
Silverlight 获取控件间的相对位置
查看>>
vscode icon in elementary os
查看>>
Android环境搭建(Windows)
查看>>
MSHFLEXGRID控件常用属性
查看>>
去除iframe滚动条
查看>>
在WORD表格按列添加时间的一种方法
查看>>