1. 程式人生 > 其它 >檔案操作和字元編碼

檔案操作和字元編碼

檔案操作和字元編碼

字元編碼的實際應用

編碼和解碼

	編碼
    	將人類能夠讀懂的字元編碼成計算機能夠直接讀懂的字元
    解碼
    	將計算機能夠直接讀懂的字元解碼成人類能夠讀懂的字元

        s1 = '事已至此 何不一搏'
    # 編碼    encode
    # print(s1.encode('gbk'))
    """
    字串前面如果加了字母b 表示該資料型別為 bytes型別
        bytes型別可以看成是二進位制
    """
    
    # 解碼    decode
    # res = b'\xca\xc2\xd2\xd1\xd6\xc1\xb4\xcb \xba\xce\xb2\xbb\xd2\xbb\xb2\xab'
    # print(res.decode('gbk'))
    """
    基於網路傳輸資料 資料都必須是二進位制格式
        所以肯定涉及到編碼與解碼
    """

字元編碼

1.字元編碼
計算機內部儲存資料都是以二進位制數字的形式儲存
計算機基於點工作 而電訊號只有高低電頻兩種狀態
我們人為的將高低電頻定義為數字1
低電頻數字為0
假如0代表你
1代表我
00 01 10 11
000 001 ....
單位換算
位元位(二進位制數的個數)
8bit = 1bytes 00000000相當於2**8種可能
1024B = 1kB
1024KB = 1MB
1024MB = 1G
1024GB = 1TB
1024TB = 1PB
我們強調的字元編碼僅限於文字檔案,其他檔案都不適用

字元編碼的發展史

#一家獨大
計算機是由美國人發明的,美國人需要計算機識別英文,所以
美國人就發明了字元編碼表(ASCII碼),這個字元編碼表
記錄了英文與數字的對應關係
1bytes 來表示所有的英文及符號。 2**8=256種
所有英文字母加起來都不超過128種可能,留有餘地
#群雄割據
中國
    中國人為了計算機識別中文,發明了我們自己的編碼表(GBK碼)
他裡面記錄了中文 英文 與數字的對應關係
GBK用2個bytes(遠遠不夠)來表示中文及符號
生僻字可能會使用更多的bytes.
日本
日本人為了計算機能夠識別日文,發明了(shift_JIS碼)
記錄了日文  英文與數字的對應關係
韓國
韓國人為了為了計算機能夠識別韓文,發明了(Euc_kr碼)
記錄了韓文  英文與數字的對應關係

#天下一統
unicode萬國碼   幾乎是所有國家文字與數字對應的關係
所有的字元用2bytes表示,不夠也是繼續增加
最後由引進utf8()
utf8轉換格式   其實是縮寫(unicode transformation format)
英文還是用1butes
中文改用3bytes
記憶體使用的編碼表是unicode   硬碟使用的是utf8
文字檔案編碼統一使用utf8

如何解決亂碼

	資料當初以什麼編碼編的就以什麼編碼解即可
    res1 = s1.encode('gbk')
    print(res1)  # 編碼
    res2 = res1.decode('euc_kr')
    print(res2)  # 亂碼
    res3 = res1.decode('gbk')
    print(res3)  # 正常顯示

python直譯器層面

	python2直譯器預設的編碼是ASCII碼
    	1.檔案頭:必須寫在檔案的最上方 告訴直譯器使用指定的編碼
            # coding:utf8
            # -*- coding:utf8 -*-  美化寫法
        2.字元字首:在使用python2直譯器的環境下定義字串習慣在前面加u
            name = u'你好啊'
    python3直譯器預設的編碼是utf8

檔案操作

# 什麼是檔案
	作業系統暴露給使用者可以直接操作硬碟的快捷方式
 
# 程式碼操作檔案的流程
	1.開啟檔案、建立檔案
    2.編輯檔案內容
    3.儲存檔案內容
    4.關閉檔案
 
# 基本語法結構
	結構1(瞭解即可):
        f1 = open()
        f1.close()
    結構2(推薦使用):
        with open() as f:
            pass
 
# 1.使用關鍵字開啟檔案
    '''以後寫路徑為了防止特殊符號 直接加r'''
    # open(r'a.txt')  # 相對路徑
    # open(r'D:\py1\day09\a.txt')  # 絕對路徑
    # res = open(r'a.txt', 'r', encoding='utf8')
    """
    open(檔案的路徑,檔案的操作模式,檔案的編碼)
        1.檔案的路徑是必須要寫的
        2.檔案的操作模式、檔案的編碼有時候不用寫(一會兒講)
    """
    # print(res.read())  # 讀取檔案內容
    # res.close()  # 關閉檔案

    """上述操作open完最後都需要執行close 而close這一行很任意被遺忘"""
    # with上下文管理
    with open(r'a.txt', 'r', encoding='utf8') as f:  # f = open()
        data = f.read()
    print(data)

檔案的讀寫方式

r	read	只讀模式:只能讀不能寫
w	write	只寫模式:只能寫不能讀
a   append   只追加模式:在檔案末尾新增內容
  
# r模式
# 路徑不存在:直接報錯
# with open(r'b.txt', 'r', encoding='utf8') as f1:
#     # pass  (推薦)補全語法結構 本身沒有任何功能
#     # ...  (不推薦)補全語法結構 本身沒有任何功能
#     pass
# 路徑存在:正常開啟檔案並等待內容讀取
with open(r'a.txt', 'r', encoding='utf8') as f1:
    # print(f1.read())  # 一次性讀取檔案內所有的內容
    f1.write('python是最牛逼的語言!!!')  # 報錯
"""
able在英語中大部分情況下表示的是 具備...的能力
    readable    具備讀的能力
    writable    具備寫的能力
    ...
"""

# w模式
# 路徑不存在:自動建立檔案
# with open(r'b.txt', 'w', encoding='utf8') as f1:
    # pass  (推薦)補全語法結構 本身沒有任何功能
    # ...  (不推薦)補全語法結構 本身沒有任何功能
    # pass
# 路徑存在:先清空檔案內容 之後再寫入資料
with open(r'a.txt', 'w', encoding='utf8') as f1:
    f1.write('你們是我見過的最優秀一批學生1\n')  # 寫入檔案內容
    f1.write('你們是我見過的最優秀一批學生2\r')  # 寫入檔案內容
    f1.write('你們是我見過的最優秀一批學生3\n')  # 寫入檔案內容
    print(f1.read())
"""
換行  最早的時候:\r\n
為了節省空間支援一個字元 根據作業系統的不同可能有所區別
    \n 、 \r
"""

# a模式
# 路徑不存在:自動建立檔案
# with open(r'c.txt', 'a', encoding='utf8') as f1:
#     pass
# 路徑存在:不會清空檔案內容 而是在檔案末尾等待新內容的新增
# with open(r'a.txt', 'a', encoding='utf8') as f1:
    # f1.write('哈哈哈哈或或或或或')
    # print(f1.read())


檔案的操作模式

#t模式		
	文字模式 是預設的模式
    	r	rt
        w	wt
        a	at
    1.該模式只能操作文字檔案
    2.該模式必須要指定encoding引數
    3.該模式讀寫都是以字串為最小單位
	
#b模式    
	二進位制模式  可以操作任意型別的檔案
    	rb  不能省略b
        wb  不能省略b
        ab  不能省略b
    1.該模式可以操作任意型別的檔案
    2.該模式不需要指定encoding引數
    3.該模式讀寫都是以bytes型別為最小單位
    
   #關於二進位制的讀寫總結
# 總結:
如果是按照二進位制開啟檔案的,要寫入或者讀取一定要編碼 解碼。
# 對於二進位制的讀與寫,要進行對應結構的編碼與解碼,編碼和解碼用相同的方式才行。中文也可以解析出。
# 寫的時候:str_bytes='I am jiyongjia嘉 !'.encode('utf-8')
# 讀的時候:str2=f2.read().decode('utf-8')

'''
如果不進行decode解碼輸出的話會是:b'I am jiyongjia\xe5\x98\x89 !' 它是一個 <class 'bytes'> 非字串,不好操作、
如果使用了decode 解碼再輸出的話,輸出結果是一個I am jiyongjia嘉 ! 它是一個 <class 'str'>

檔案的內建方法

read()  # 一次性讀取檔案內容
	1.執行完之後游標在檔案末尾 繼續讀取沒有內容
    2.當檔案內容特別大的時候 容易造成記憶體溢位(滿了)
readline()  # 一次只讀一行內容
readlines()  # 結果是一個列表 裡面的各個元素是檔案的一行行內容
readable()  # 判斷當前檔案是否可讀
支援for迴圈  # 一行行讀取檔案內容(推薦使用)  記憶體中同一時刻只會有一行內容
write()  # 寫入檔案內容(字串或者bytes型別)
writelines()  # 可以將列表中多個元素寫入檔案
writable()  # 判斷檔案是否可寫
flush()  # 相當於主動按了ctrl+s(儲存)