亂碼問(wèn)題原因分析

自己經(jīng)常在Linux和Windows下使用各種各樣的軟件,經(jīng)常遇到的亂碼的問(wèn)題。

之前的對(duì)策是google XX軟件 亂碼 得到的結(jié)果往往是這樣子的

Step1... Step2... Step3... ....

于是自己也跟著做,有時(shí)能成功,但有時(shí)依然亂碼,只好放棄使用這個(gè)軟件。

我想我的問(wèn)題一直不知道為什么會(huì)出現(xiàn)亂碼,當(dāng)然,并不是完全不知,說(shuō)起編碼,也能說(shuō)出個(gè)一二三來(lái),什么unicode, utf-8, 轉(zhuǎn)換編碼之類(lèi)的。但自己并沒(méi)有一個(gè)清晰的概念。所以一直出問(wèn)題,也不知道問(wèn)題的根源在哪里。所以出了問(wèn)題,解決問(wèn)題的方式只能上網(wǎng)搜索,純屬碰運(yùn)氣。

直到前一段時(shí)間讀到The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets這篇文章,發(fā)現(xiàn)自己有了那么一點(diǎn)點(diǎn)清晰的概念,之后在學(xué)Python Module of the Week中的編碼時(shí),仔細(xì)思考了一下,總算把亂碼產(chǎn)生的原因想的大概明白了。

其實(shí),說(shuō)起來(lái)很簡(jiǎn)單,對(duì)于文本來(lái)說(shuō),主要有兩種操作

  1. 將文本寫(xiě)入文件
  2. 從文件中讀取

其中如果寫(xiě)入文件時(shí)和讀取文件時(shí)使用的編碼不一樣,則可能會(huì)產(chǎn)生亂碼,到這里似乎還很簡(jiǎn)單。

一般情形是這樣子的,使用一個(gè)文件編輯器編輯一個(gè)文件,然后保存,保存的時(shí)候選取某一種編碼,這一過(guò)程對(duì)應(yīng) 1. 寫(xiě)入文件時(shí)的編碼

讀取文件時(shí),往往使用文本編輯器打開(kāi)一個(gè)文件,如果此時(shí)文本編輯器設(shè)定的編碼方式與文件保存時(shí)使用的編碼方式一樣,那么顯示的時(shí)候就不會(huì)有亂碼,如果不一樣,則可能產(chǎn)生亂碼(如果保存時(shí)使用的編碼是顯示時(shí)設(shè)置的編碼的子集,一般會(huì)正常顯示)。這一過(guò)程對(duì)應(yīng) 2. 從文件中讀取 。

由以上可以看的出來(lái),使用文本編輯器保存時(shí)是寫(xiě)入,使用文本編輯器打開(kāi)文件時(shí)是讀取。這種情況很簡(jiǎn)單。

但是, 寫(xiě)入文件讀取文件 并非只有以上這種方式,而且 文件 也有可能不是通常所見(jiàn)到的那種。

寫(xiě)入文件 還可以是使用程序來(lái)生成一個(gè)文件,如

with codecs.open(filename, mode='w', encoding=encoding) as f:
    f.write(u'pi: \u03c0')

以上Python代碼,這時(shí),就要在代碼中設(shè)置寫(xiě)入時(shí)的編碼方式。這個(gè)還只是寫(xiě)入到普通文件。如果是程序員,應(yīng)該還知道有一種文件叫做 標(biāo)準(zhǔn)輸出文件 而這種文件并不一定是傳統(tǒng)意義上的文件。而且,這里有一個(gè)比較容易誤解

標(biāo)準(zhǔn)輸出文件就是控制終端

其實(shí),標(biāo)準(zhǔn)輸出文件并不一定是控制終端,只不過(guò)常常和控制終端相連接,所以才有此誤解。

好,現(xiàn)在的最復(fù)雜的情況是在程序中寫(xiě)內(nèi)容到標(biāo)準(zhǔn)輸出文件需要指定編碼。

接下來(lái)的問(wèn)題是,既然內(nèi)容按照一定的編碼寫(xiě)到了標(biāo)準(zhǔn)輸出,這是一個(gè)寫(xiě)文件的過(guò)程,那么讀文件呢?

以下討論兩種情況。

  1. 標(biāo)準(zhǔn)輸出與終端連接:標(biāo)準(zhǔn)輸出往往與終端連接,將內(nèi)容顯示在終端上,這里其實(shí)已經(jīng)有了一個(gè)讀文件的過(guò)程。在傳統(tǒng)的讀文件過(guò)程中,有一個(gè)文本編輯器,有一個(gè)打開(kāi)文件的過(guò)程,但這里標(biāo)準(zhǔn)輸出文件并不是一個(gè)可以看的見(jiàn)的實(shí)體。而這個(gè)過(guò)程中,文本編輯器又在哪里呢?呵呵,這里 充當(dāng)文本編輯器角色的正是終端 。 所以通常所說(shuō)的設(shè)置終端的編碼就如同使用設(shè)置文本編輯器的編碼一樣。
  2. 標(biāo)準(zhǔn)輸出與管道連接:這里負(fù)責(zé) 讀文件 的是管道之后的程序。所以這里需要設(shè)置管道之后的程序中讀文件所使用的編碼。具體例子見(jiàn)PyMOTW中的codecs_stdin.py

其實(shí)要想搞清整個(gè)過(guò)程,有三個(gè)關(guān)鍵點(diǎn)最重要

  1. 寫(xiě)入過(guò)程指的是什么?
  2. 讀出過(guò)程指的是什么?
  3. 文件又指的是什么?

涉及文本操作的均離不開(kāi)以上三個(gè)部分,分析一個(gè)文本操作,找出以上三個(gè)部分的答案,讓寫(xiě)入過(guò)程和讀出過(guò)程的編碼一致,就能解決亂碼問(wèn)題了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容