有關linux與windows中文件名的編碼問題總結

最近在整理各類褲子,因爲太大用了ntfs-3g掛載硬盤,拷貝到了centos服務器上,結果沒有注意文件名的編碼問題,總要修改因此說config/i18n配置文件,並且經過ssh鏈接要常常切換客戶端的字符集,無奈,拷回硬盤上,在window上弄吧,結果,文件名出現各類亂碼。。。。崩潰了。安心學習了。。。linux

(其中涉及到了ntfs-3g,ssh遠程客戶端,以及linux的/etc/sysconfig/i18n配置,沒有一一測試,除了ntfs-3g不知道是否涉及字符集,其餘都涉及到了,思路比較亂,想到哪寫到哪了)windows

問題根源:因爲Linux與windows採用了不一樣的字符集來處理中文文件名,Linux用了utf-8而windows用了gbk,進而致使文件名處理的混亂。centos

個人作法是:服務器

一、利用convmv 在linux上將全部文件名編碼轉換爲gbk,再經過ntfs-3g將文件拷到移動硬盤,最後拷回電腦,在windows上可以正常顯示。ssh

二、處理文件工具

三、將文件拷回linux學習

四、利用convmv將文件名轉回utf8測試

因爲習慣了在windows上開發, 想本身寫一個py腳本實如今windows上將文件名字符編碼進行轉換的功能,可是立刻問題就出現了。編碼

下面請看:spa

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的現象,所以若是想實現此功能須要修改底層實現。 

相關文章
相關標籤/搜索