1. 程式人生 > >字元編碼,檔案處理

字元編碼,檔案處理

軟體啟動的流程
開啟notepad++ 來檢視test.txt文件
1.從硬碟將軟體程式載入到記憶體中
2.載入test.txt到記憶體中
3.執行notepad的程式碼將test.txt的內容輸出到螢幕上

python直譯器也是一個應用軟體
1.從硬碟將直譯器載入到記憶體中
2.載入test.py到記憶體中
3.直譯器解析python語法



文字編輯器與直譯器在開啟同一個py檔案時
前兩個階段是一致的,僅僅是第三個階段不同


什麼是字元編碼?字元編碼表
   編碼,按照某種規範 將資料轉換為二進位制
為什麼要編碼?
   計算機只能識別0/1,那麼要使用計算機則必須將所有的資料和命令都用二進位制表示
   這是一個複雜的過程,所以需要一種解決方案,可以讓計算機識別人類的語言

字元編碼的發展史
   美國人發明了計算機,需要讓計算機識別美國人的語言,所以誕生了asc編碼表
   其他的國家也需要使用計算機,於是每個國建都退出了自己的編碼表
   中國-GBK
   日本-shift-j
   因為每個編碼表互不相容,導致亂碼問題
   為了統一全世界的編碼 推出而unicode編碼
   1.統一全世界的編碼
   2.必須還相容之前的GBK,shift-j

ASCII 中用八個二進位制(1個bytes)

GBK 英文字母佔一個位元組
    中文佔兩個位元組
    16個二進位制 2**16-1=65535
   如果一個位元組的首位為1 表示一箇中文
   若果一個位元組的首位為0 表示一個英文
    GBK不僅僅要儲存資料 還要計算每一個符號佔的長度

unicode 無論英文還是其他字元 都是2個位元組
   為什麼這麼設計?不浪費空間?
   1.為了提高效率,而採取的空間換時間(效率)
   unicode的問題
   浪費空間,降低網路傳輸效率

為了解決上述unicode的問題、:退出了UTF-8
   utf-8是變長的
   英文佔一個位元組
   中文佔三個位元組
   生僻字佔更多位元組

   與GBK相同的是,都需要計算,所以不適用於記憶體
   適用於:硬碟和網路傳輸

結論就是  記憶體中用unicode,硬碟或網路中用UTF-8

使用者輸入->記憶體(unicode)->轉換成(utf-8)->硬碟 該過程稱之為編碼 就是字元轉為二進位制的過程
硬碟上的a.txt(utf-8的二進位制)-> 記憶體中unicode的二進位制—>查編碼表得到符號->顯示到螢幕上
該過程稱之為解碼 把二進位制轉為符號

亂碼問題?
    1.儲存時與取出時使用的編碼方式不一致
亂碼不僅僅是因為存和取的編碼不同,還可能是存的時候就已經亂了,這將導致資料流失!
所以存的時候一定要注意:
  所使用的編碼方式一定要支援文件中的所有內容,即utf-8

python在執行程式碼之前必須從硬碟載入程式碼到記憶體,而硬碟中都是二進位制資料,必須先解碼為unicode
那直譯器怎麼知道擬採用的什麼編碼方式?
如果不明確自定 直譯器將採用預設的解碼方式,在python3中預設為utf-8而python2中預設為ASC
當你使用的是py2的時候 則需要手動制定編碼方式,在文件的第一行寫上 coding:uft-8
coding:uft-8

py2中當從記憶體訪問變數時可能會亂碼,例如儲存時utf-8的字元但是輸出時 卻用了GBK
python2中u 表示 將這個變數儲存為unicode編碼 可以防止取出變數時亂碼
資料型別也變為了unicode
1個16進位制 = 0.5個位元組

encode: unicode->uft-8 將unicode的字元 轉為自定的二進位制
decode: utf-8 ->unicode 將二進位制轉為unicode

檔案處理:

檔案是什麼?
  檔案是作業系統提供的一套虛擬概念
檔案這個概念之所以出現 是為了簡化對硬碟的操作
學習檔案處理是為了將資料永久儲存

開啟檔案的語法1
1.開啟檔案
  f=open('test.txt',encoding='utf-8')#是給系統傳送了一個指令,讓作業系統去開啟檔案,因為應用程式無法直接控制硬體
  
2.讀取內容
  data=f.read()
  print(data)
  
3.關閉檔案 不要忘記關閉
  f.close()

open close read等都是在給作業系統傳送指令

開啟檔案的語法2:  在with程式碼執行完畢後會自動呼叫close
with open ('test.txt',encoding='utf-8') as f:
    data= f.read()
    print(data)

引數1 檔案路徑 可以是相對 也可以是絕對
mode 開啟檔案的模式 
 r(只讀)
 w(只寫)
 
 +(可讀可寫)瞭解即可
  + 表示可讀可寫
  w+ 清空原始檔如果不存在則建立
  r+ 如果不存在則報錯
  a+ 如果不存在則建立,游標移動到最後
  可讀可寫 可用於文字處理 但是對於寫別的檔案,一般不用,很容易造成檔案損壞
 
encoding 編碼方式 windows預設為GBK Linux預設為utf-8

讀取內容 可以用引數指定要讀取的個數,預設為-1 表示全部讀取
需要注意 read(-1)僅限於檔案較小時,如果檔案太大會造成記憶體溢位
data=f.read(2000)
f.readable() 判斷是否可讀
f.writable()判斷是否可寫
line=f.readline()

使用迴圈 來讀取全部內容1
with open(r'D:\ \ \ ,encoding='utf-8') as f:
    while True:
    line = f.readline()
    if not line:#如果line為空則表示沒有內容了
           break
    print(line,end='')
使用迴圈 來讀取全部內容2
with open(r'D:\ \ \ ,encoding='utf-8') as f:
    for line in f:
        print(line,end='') 
           
使用迴圈 來讀取全部內容3
#一次性讀取全部
with open(r'D:\ \ \ ,encoding='utf-8') as f:
  print(f.readlines())#會將每行放入列表中

讀取相關函式
read()     讀取全部
read(size) 讀取指定大小
readlines  讀取全部
readlin    讀取一行
readable   是否可讀

注意在W模式寫 一旦開啟檔案 立即清空原來的內容 如果檔案不存在則建立新檔案
寫入字串時需要手動拼接換行符
with open(r'D:\ \ \ ,mode='w',encoding='utf-8') as f:
    f.write('矮跟')
    f.writelines('\n'.join(....))


在操作非文字檔案時,必須明確指定為位元組模式
b 用來指定為位元組模式
注意:
b 必須與r\w連用 rb(readBytes)\wb(writeBytes)
當檔案為位元組模式時 不能指定encoding引數!

預設情況下時讀寫文字模式 也就是t模式同樣需要與r\w連用
rt(readText)\wt(writeText)
t模式下 python直譯器會自動進行編碼和解碼而b模式不會

當模式為位元組模式時(rb)單位為位元組
#迴圈讀取全部內容

with open('xxx.png',mode='rb') as f:
    while True:
    data = f.read(1024)
    if not data:#如果data為空則意味著檔案讀完了
         break
    print(data)
    
    
在b模式只能寫入位元組


追加寫入: a 表示追加寫入 不會清空原資料 會把游標移動到最後

控制檔案的開啟模式
    r\w\a
控制操作檔案內容的模式
    t\b
    
t\b 必須與開啟模式連用
各種組合如下:
rt wt at rb wb ab r+ w+ a+

關於檔案操作的常用函式
read
readline
readlines
readable

write
writelines
writeable

關於編碼的兩個函式
encode  編碼
decode  解碼