1. 程式人生 > >05 python開發之檔案處理

05 python開發之檔案處理

# 05 python開發之檔案處理 [TOC] # 5 檔案處理 ## 5.1 字元編碼 ### 5.1.1 基本概念 - 字元編碼 文字元號-----------------編碼----------------->數字 文字元號<----------------編碼------------------數字 - 字元編碼表:一個字元對應一個數字 - 研究字元編碼表是為了解決亂碼問題 存取都用同一張字元編碼表 - 儲備知識:CPU、記憶體、硬碟 - 執行python程式的三個階段 Ⅰ 先啟動一個python直譯器 Ⅱ python直譯器會將檔案內容從硬碟讀入記憶體 Ⅲ python直譯器會解釋執行剛剛讀入記憶體的程式碼,識別語法 x = "你好Hello" ### 5.1.2 發展歷程 - 一家獨大 ASCⅡ:只能識別英文字元,用8個bit對應一個英文字元 - 天下大亂 GBK:能識別中文和英文,用16個bit(2Bytes)對應一個字元 shift-JIS Euc-KR - 歸於統一 unicode:能識別萬國字元,常用16bit(2Bytes)對應一個字元 ### 5.1.3 使用 - part1 ​ 英文字元------->記憶體(ASCⅡ格式的二進位制數)---->硬碟(ASCⅡ格式的二進位制數) 中文、英文字元------->記憶體(GBK格式的二進位制數)----->硬碟(GBK格式的二進位制數) 日文、英文字元--->記憶體(shift-JIS格式的二進位制數)--->硬碟(shift-JIS格式的二進位制數) ​ 萬國字元----->記憶體(Unicode格式的二進位制數)---->硬碟(utf-8格式的二進位制數) - part2 ```python 字元-------->unicode格式的二進位制(記憶體)---------------->utf-8格式的二進位制(硬碟) 編碼 編碼 字元<--------unicode格式的二進位制(記憶體)<----------------utf-8格式的二進位制(硬碟) 解碼 解碼 x = "上" print(x) # 列印unicode相當於列印字元 utf8_res = x.encode("utf-8") # print(utf8_res, type(utf8_res)) # b'\xe4\xb8\x8a' unicode_res = utf8_res.decode("utf-8") print(unicode_res) ``` ## 5.2 檔案處理基礎 ### 5.2.1 基本概念 - 檔案是作業系統提供給使用者/應用程式存取硬碟的一種機制 - 檔案可以永久儲存資料 - 如何使用檔案 應用程式 open() 作業系統 檔案 計算機硬體(硬碟) ### 5.2.2 操作檔案的步驟 - rawstring原生路徑 f = open(r'檔案絕對路徑/相對路徑') f的值,檔案物件/檔案控制代碼 - data = f.read() print(data) - f.close() # 回收系統資源 ### 5.2.3 with上下文管理 ```python with open(r'絕對路徑或相對路徑') as f1,\ open(r'絕對路徑或相對路徑') as f2: f1.read() f2.read() with open(r'第二週計劃', "rt", encoding='utf-8') as f1: data = f1.read() print(data) f1.close() data = f1.read() print(data) ``` ## 5.3 檔案開啟模式 ### 5.3.1 控制讀寫操作模式 - r : 只讀(預設) - w : 只寫 - a : 只追加寫 ### 5.3.2 控制讀寫內容的模式 - t : 讀寫都是文字格式,即讀寫都是用字串(預設) - b : 讀寫都是bytes格式,bytes等同於二進位制 強調:如果是t模式,一定要加上encoding="編碼格式" ​ 如果是b模式,一定不可以加上encoding="編碼格式" ### 5.3.3 常規使用 - r:在檔案存在的時候,檔案指標調到檔案的開頭,檔案不存在直接報錯 ```python r:在檔案存在的時候,檔案指標調到檔案的開頭,檔案不存在直接報錯 f = open("a.txt", mode="rt", encoding="utf-8") res = f.read() print(res) f.close() ``` - w:在檔案存在的時候會清空檔案,指標調到檔案開頭,檔案不存在會建立空新檔案 ```python w:在檔案存在的時候會清空檔案,指標調到檔案開頭,檔案不存在會建立空新檔案 f = open("a.txt", mode="wt", encoding="utf-8") f.write("你好\n666") f.close() ``` - a:在檔案存在的時候不會清空檔案,指標跳到檔案末尾,檔案不存在會建立空新檔案 ```python a:在檔案存在的時候不會清空檔案,指標跳到檔案末尾,檔案不存在會建立空新檔案 f = open("a.txt", mode="at", encoding="utf-8") f.write("\n777") f.close() ``` - rb wb ab ```python rb wb ab f = open("a.txt", mode="rb") res = f.read() print(res) print(res.decode("utf-8")) f.close() f = open("a.txt", mode="wb") f.write("你好".encode('utf-8')) f.close() ``` - 圖片、視訊等非文字檔案只能用b模式 ```python with open(r'H:\BaiduNetdiskDownload\Linux階段總結\img\day004主機板.png', mode='rb') as f1,\ open(r'C:\Users\曹嘉鑫\Desktop\1111.png', mode='wb') as f2: # res = f1.read() # f2.write(res) for line in f1: f2.write(line) ``` ### 5.3.4 拓展功能 ```python with open('a.txt', mode='r+t', encoding='utf-8') as f: print(f.read()) print(f.writable()) print(f.readable()) f.write("你好") with open('a.txt', mode='w+t', encoding='utf-8') as f: print(f.writable()) print(f.readable()) f.write("你好") res = f.read() print("===> %s" % res) with open('a.txt', mode='a+t', encoding='utf-8') as f: print(f.writable()) print(f.readable()) print(f.read()) f.flush() print(f.name) print(f.encoding) ``` ## 5.4 檔案處理的其他辦法 ### 5.4.1 讀操作 ```python with open('a.txt', mode='rt', encoding='utf-8') as f: line1 = f.readline() print(line1) line2 = f.readline() print(line2) for line in f: print(line) lines = f.readlines() print(lines) ``` ### 5.4.2 寫操作 ```python with open('a.txt', mode='wt', encoding='utf-8') as f: f.write("1111\n2222\n3333\n") for x in "hello": f.write(x) f.writelines("hello") # f.write("hello") f.writelines(["111", "222", "333"]) f.writelines(["111\n", "222\n", "333\n"]) ``` ## 5.5 控制指標移動 ### 5.5.1 重要概念 - 檔案內指標移動,除了t模式下的read(n)中n代表的是字元個數 - 其他都是以bytes為單位的 ```python with open('a.txt', mode='rt', encoding='utf-8') as f: res = f.read(6) print(res) with open('a.txt', mode='rb') as f: res = f.read(8) print(res) print(res.decode('utf-8')) with open('a.txt', mode='r+', encoding='utf-8') as f: f.truncate(8) ``` ### 5.5.2 f.seek() - f.seek(移動的位元組個數,模式) - 三種模式 0 : 參照檔案開頭移動指標 1 : 參照當前所在的位置移動指標 2 : 參照檔案末尾位置移動指標 - 只有0模式可以在t下使用 - 1和2只能在b下使用 ```python 只有0模式可以在t下使用,1和2只能在b下使用 with open('a.txt', mode='a+b') as f: print(f.tell()) # 檢視指標在檔案的第幾個位元組 with open('a.txt', mode='r+b') as f: f.seek(0, 2) print(f.tell()) with open('a.txt', mode='a+b') as f: f.seek(-6, 2) # print(f.read().decode('utf-8')) print(f.read(3).decode('utf-8')) import time with open('a.txt', mode='rb') as f: f.seek(0, 2) while True: line = f.readline() if len(line) == 0: time.sleep(0.1) else: print(line.decode('utf-8'), end="") ``` ## 5.6 檔案修改的兩種方式 ```python # 方式一: # 1、以r模式開啟原始檔,將原始檔內容全部讀入記憶體 # 2、在記憶體中修改完畢 # 3、以w模式開啟原始檔,將修改後的內容寫入原始檔 # 優點:不必大量佔用硬碟資源 # 缺點:耗記憶體,需要足夠的記憶體空間 with open('a.txt', mode='rt', encoding='utf-8') as f1: data = f1.read() res = data.replace('hello', '早上好') with open('a.txt', mode='wt', encoding='utf-8') as f2: f2.write(res) # 方式二: # 1、以r模式開啟原始檔,然後以w模式開啟一個臨時檔案 # 2、從原始檔中讀一行到記憶體中,修改完畢後直接寫入臨時檔案,迴圈往復直到操作完畢所有行 # 3、刪除原始檔,將臨時檔名改為原始檔名 # 優點:沒有對記憶體造成過度的佔用 # 缺點:需要硬碟預留出足夠的空間來存放臨時檔案 import os with open('a.txt', mode='rt', encoding='utf-8') as src_f,\ open('.a.txt.swp', mode='wt', encoding='utf-8') as dst_f: for line in src_f: dst_f.write(line.replace('你好', 'Hello')) os.remove('a.txt') os.rename('.a.txt.swp', 'a.txt') ``` ## 5.7 Type hinting ```python # Type hinting def add(x: int, y: int) -> int: res = x + y return res print(add.__annotations__) # {'x': , 'y': , 'return':