剛來這個公司,熟悉了環境,老大就開始讓我做一個遷移、修改代碼的工作,我想說的是,這種工作真沒勁~~,看別人的代碼、改別人的代碼、這裡改個變量、那裡改個文件名······,都是些沒技術含量、很繁瑣的事情,不過通過遷移代碼順便熟悉下環境也好。扯了這麼多,說說今天的主題吧——代碼編碼格式改變,由於某些原因,需要將代碼從A機房遷移到B機房,這兩個之間不能互相訪問,但是歷史原因導致A機房的代碼全是utf8編碼的,B機房要求是GBK編碼,看看這個怎麼解決。
編碼問題
先說說為什麼會有編碼問題,就拿上面那個例子來說,B機房這邊數據庫全是GBK編碼的,因此從數據庫中取出來的數據都是GBK的,從數據庫中取出來的數據是GBK編碼的,要在展示的時候不亂碼,在不對數據庫取出的數據轉換的情況下,就需要發送header的時候設置編碼為GBK,輸出的文件(html、tpl等)都必須是GBK的,看看下面這個圖會更清楚點:
DB(GBK) => php等(編碼格式不限但如果代碼文件中有漢字,文件就要是gbk編碼或者在漢字輸出的時候轉化為gbk) => header(GBK) => html、tpl(GBK)
或者還有一種方式只在出庫的時候在代碼中將utf8轉化為gbk,總的來說utf8還是更流行點,問題更少點
DB(GBK) => php等(utf8,並將從數據庫取出的數據轉化為utf8) => header(utf8) => html、tpl(utf8)
只要按照上面這兩種規范編碼格式,就不會出現亂碼情況,起碼我測試的第一種方式是沒問題的,所以我猜第二種也ok,好了,現在就來寫一個轉換文件編碼格式的小腳本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #!/usr/bin/python # -*- coding: utf-8 -*- #Filename:changeEncode.py import os import sys def ChangeEncode(file,fromEncode,toEncode): try: f=open(file) s=f.read() f.close() u=s.decode(fromEncode) s=u.encode(toEncode) f=open(file,"w"); f.write(s) return 0; except: return -1; def Do(dirname,fromEncode,toEncode): for root,dirs,files in os.walk(dirname): for _file in files: _file=os.path.join(root,_file) if(ChangeEncode(_file,fromEncode,toEncode)!=0): print "[轉換失敗:]"+_file else: print "[成功:]"+_file def CheckParam(dirname,fromEncode,toEncode): encode=["UTF-8","GBK","gbk","utf-8"] if(not fromEncode in encode or not toEncode in encode): return 2 if(fromEncode==toEncode): return 3 if(not os.path.isdir(dirname)): return 1 return 0 if __name__=="__main__": error={1:"第一個參數不是一個有效的文件夾",3:"源編碼和目標編碼相同",2:"您要轉化的編碼不再范圍之內:UTF-8,GBK"} dirname=sys.argv[1] fromEncode=sys.argv[2] toEncode=sys.argv[3] ret=CheckParam(dirname,fromEncode,toEncode) if(ret!=0): print error[ret] else: Do(dirname,fromEncode,toEncode)腳本很簡單,使用也很簡單
代碼如下:
這裡要注意下,幾種常見編碼的關系:
us-ascii編碼是utf-8編碼的一個子集,這個是從stackoverflow上得到的,原文如下ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded,
我試了下確實是的,在不加漢字的時候顯示編碼為us-ascii,加了漢字之後,變為utf-8。
還有就是ASNI編碼格式,這代表是本地編碼格式,比如說在簡體中文操作系統下,ASNI編碼就代表GBK編碼,這點還需要注意
還有一點就是一個在linux下查看文件編碼格式的命令是:
file -i *
可以看到文件的編碼格式。
當然了,上面的可能有些文件中有特殊字符,處理的時候會失敗,但一般程序文件是沒有問題的。