檔案操作簡介:
使用python來讀寫檔案是非常簡單的操作.我們使用 open() 函式來開啟一個檔案,獲取到檔案控制程式碼.然後
通過檔案控制程式碼就可以進行各種各樣的操作了.根據開啟⽅方式的不同能夠執行的操作也會有相應的差異.
開啟檔案的方式: r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b 預設使⽤用的是r(只讀)模式
相對路徑 絕對路徑:
絕對路徑:從磁碟根目錄開始尋找到檔案目錄 如:E:Python_workspace 王尼瑪.txt
相對路徑:從檔案儲存路徑尋找,若在同一層資料夾中,則相對路徑就是檔名,
若是上一層.則加上 ../ 以此類推
只讀操作模式(r rb):
r 開啟檔案open() 讀取第n個字元.read(n)
1 # r 開啟檔案open() 讀取第n個字元.read(n)
2 f = open("操作檔案.txt",mode="r",encoding="utf-8") # f 變數 操控檔案的控制程式碼
3 # 注意encoding表示編碼集.根據檔案的實際儲存編碼(windows預設為gbk)進行獲取資料,常用utf-8
4 content = f.read(3) # 讀取第三個字元
5 # content1 = f.read() # 一次性讀取全部字元
6 print(content)
7 # print(content1)
8 f.close()
9 # 注意read(n)讀取第n個字元,若再次讀取時會在 當前位置繼續 去讀而不是從頭去讀取
rb 常用於非文字檔案 在rb模式下.不能選擇encoding字符集.
1 # rb 常用於非文字檔案 在rb模式下.不能選擇encoding字符集.
2 f = open("../問題1.jpg",mode="rb")
3 content = f.read()
4 print(content) # 返回位元組 b`xffxd8xffxe0x00x10JFIFx00......`
5 f.close()
6 # read() 將檔案內容全部讀取出來 ,缺點:佔記憶體,若檔案過大容易導致崩潰
readline() 讀取一行資料
1 f = open("../王尼瑪.txt",mode="r",encoding="utf-8")
2 s = f.readline() # 讀取一行資料
3 print(s.strip()) # stirp() 去掉空白 空格
4 f.close()
readlines()將每一行形成一個元素,放到列表中.所有的內容都讀取出來.容易出現記憶體崩潰的問題.
1 lis = f.readlines() # 一次性全讀取出,返回列表
2 lis1 = []
3 for i in lis:
4 lis1.append(i.strip())
5 print(lis1)
6 # readline() readlines()和read()一樣 多次讀取時不是從頭開始 而是接著上面
轉義字元有固定含義 推薦用 r 取消功能
1 f = open(r"E:Python_workspace
666.txt",mode="r",encoding="utf-8")
2 print(f.read())
3 f.close()
read() readlines()都不推薦使用甚至是不使用,特別是在生產環境裡!!
1 # read() readlines()都不推薦使用甚至是不使用,特別是在生產環境裡!!
2 # 若需要讀取 可通過 readline() 一次讀取一行 以及迴圈讀取
3 # 迴圈讀取
4 # # 檔案控制程式碼是一個可迭代物件(必須掌握)
5 f = open("../王尼瑪.txt",mode="r",encoding="utf-8")
6 for line in f: # 當成list讀取檔案內容 一行一行的讀取 每次讀的內容都交給前面的變數
7 print(line.strip())
8 f.close()
注意讀取完檔案控制程式碼一定要關閉 f.close()
追加(a,ab)
1 # 只要是a或者ab,a+ 都是在檔案的末尾寫入.不論游標在任何位置.
2 f = open("../王尼瑪.txt",mode="a",encoding="utf-8")
3 f.write("這是一隻後入的王尼瑪!")
4 f.flush()
5 f.close()
6 # ab a+ 模式下一樣
# mode:
# r:只讀
# w:寫, 先清空裡面的內容. 然後再寫入
# a: 追加寫入.
檔案操作: w
只寫 w
注意.寫入時,若沒檔案.則會建立檔案,如果檔案存在.則將刪除(首次)原內容,再寫入新內容
1 f = open("哇哈哈.txt",mode="w",encoding="utf-8") # 建立新檔案
2 f.write("哇哈哈,爽歪歪")
3 f.flush() # 重新整理 養成好習慣
4 f.write(" 優酸乳,美滋滋啊") # 第二次write不會刪除原內容 僅僅寫入新內容
5 # f.read() # 只寫模式 不能讀取 報錯 not readable
6 f.close() # 關閉控制程式碼
只寫 位元組 wb
1 # wb模式下.可不指定檔案的編碼.但在寫檔案時必須將字串轉化成utf-8的bytes資料
2 f = open("小屁孩.txt",mode="wb")
3 f.write("wusir".encode("utf-8")) # 寫入時必須轉化成bytes資料
4 f.flush()
5 f.close()
文字檔案的複製:
1 f1 = open(r"e:Python_workspace王尼瑪.txt",mode="r",encoding="utf-8")
2 f2 = open(r"g:王尼瑪.txt",mode="w",encoding="utf-8")
3 for line in f1: # 從f1讀取資料到變數
4 f2.write(line) # 寫入到f2中(關於寫入清空:清空只會在open開啟再首次write時清空,這裡顯然不是)
5 f1.close()
6 f2.close()
7 #
8 # gbk utf-8 為文字編碼 這裡的複製方法只適用於文字
9 # 若是圖片/視訊/音訊等需編碼成bytes再操作,見下
rb wb ab 把字元換成位元組 僅此而已
b - bytes 讀取和寫入的是位元組,用來操作非文字檔案(圖片, 音訊, 視訊)
1 # 複製一張圖片 從E盤到G盤,單純的從bytes角度來複制(bytes適用於所有檔案)
2 f = open(r"E:Python_workspace問題1.jpg",mode="rb")
3 f1 = open(r"g:問題1.jpg",mode="wb")
4
5 for line in f: # 分批量讀取bytes內容(複製的是 01 程式碼)
6 f1.write(line) # 因為f1的mode模式有w寫入
7 f.close()
8 f1.close()
r+ 讀寫 w+ 寫讀 a+ 追加寫讀 :
# r+b 讀寫轉換成位元組 w+b 寫讀轉換成位元組 a+b 追加寫讀換成位元組
# + 擴充套件
# r+ 讀寫 (較為常見的)
1 # 正確的操作 先讀後寫 2 f = open("person",mode="r+",encoding="utf-8") 3 content = f.read() 4 f.write("黃蓉") 5 print(content) 6 f.close() 7 # 正常的讀取之後,寫在結尾
1 # 錯誤的操作 2 f = open("person",mode="r+",encoding="utf-8") 3 f.write("趙敏") # 預設直接寫入的話,在開頭寫入,會覆蓋開頭的內容 4 content = f.read() 5 print(content)
1 # 坑 不論讀取多少內容,再次寫入時都是在末尾 2 f = open("person",mode="r+",encoding="utf-8") 3 content1 = f.read(3) 4 f.write("郭芙") 5 print(content1) 6 f.close()
# 深坑請注意:在 r+ 模式下.如果讀取內容.不論讀取內容多少.顯示的是多少.再寫入或者操作檔案時候都是在結尾進行的操作.
# w+ (幾乎用不到) (先清空再寫入)
1 # w+ (幾乎用不到) (先清空再寫入) 2 f = open("person",mode="w+",encoding="utf-8") 3 f.write("你好,世界") # 開啟就寫入會直接清空內容 4 content = f.read() # 寫入內容後 游標在末尾 讀取不了內容 5 print(content) 6 f.close()
# a+ (很少使用) 追加寫讀
1 # a+ (很少使用) 追加寫讀 2 # 不論游標在何處 寫入的時候都是在末尾 3 f = open("person",mode="a+",encoding="utf-8") 4 f.write("東方不敗") # 預設寫在末尾 5 content = f.read() 6 print(content) 7 f.close()
游標 seek(引數1,引數2):
# seek(引數1,引數2)
# 引數1表示的是偏移量,移動多少個單位
# 引數2表示從什麼位置進行偏移
# 0: 開頭
# 1: 當前位置
# 2: 末尾
# 游標移動到n位置,注意移動的單位是byte,所以如果是utf-8中文部分則為3的倍數。
# 移動到開頭:seek(0)
# 移動到結尾:seek(0,2)
1 f = open("person",mode="r",encoding="utf-8") 2 f.seek(0) # 以位元組為單位 3 f.seek(2) 4 print(f.read(2)) # 讀取兩個字元
1 # tell() 返回當前游標的位置 2 info = f.read(3) # utf-8 3*3 9個位元組 3 print(info) 4 print(f.tell()) # 獲取游標的位置
# truncate() 擷取截斷檔案(慎用)(特別伺服器內)
1 f = open("person",mode="w",encoding="utf-8") 2 f.seek(3) # 游標移動到3 3 print(f.tell()) 4 # f.truncate() # 後面所有內容都刪掉 5 f.truncate(3) # 從頭到3擷取 6 f.close()
# 檔案修改:
固定模組 import.os
os.remove()
os.rename()
1 import os # 匯入 os 模組 2 3 import time # 匯入時間模組 4 5 # 優點: 不使用控制程式碼,自動關閉連線 6 with open("唐詩",mode="r",encoding="utf-8") as f1, 7 open("唐詩_副本",mode="w",encoding="utf-8") as f2: 8 for line in f1: 9 line = line.replace("與","yu") 10 f2.write(line) 11 time.sleep(3) 12 os.remove("唐詩") # 刪除原始檔 13 time.sleep(3) 14 os.rename("唐詩_副本","唐詩") # 把副本改名成原始檔
# 檔案操作應用練習:
# 把資料歸類 增添資料時自動按格式排列
```
1,榴蓮,500,60000
2,蘋果,700,70000
3,荔枝,600,60000
4,西瓜,800,70000
```
1 # 1. 2 f = open(r"水果.txt",mode="r",encoding="utf-8") 3 lis = [] 4 for line in f: 5 lis.append(line) 6 print(lis) # 沒有清晰的分類 僅把每排關聯資料作為一個元素裝到了lis 7 # [`1,榴蓮,500,60000 `, `2,蘋果,700,70000 `, `1,榴蓮,500,60000 `, `2,蘋果,700,70000`]
1 # 2. 2 lis = [] 3 # dic = {} # 迴圈 不可放在這裡 4 f = open(r"水果.txt",mode="r",encoding="utf-8") 5 for line in f: # "1,蘋果,500,60000"——》弄成字典效果——》{id:1,name:蘋果, num:500, price:60000} 6 dic = {} # dic定義字典變數不可放在迴圈之前 否則只會有一個元素重複新增到lis 7 li = line.strip().split(",") 8 dic["id"] = li[0] 9 dic["name"] = li[1] 10 dic["num"] = int(li[2]) 11 dic["price"] = int(li[3]) 12 lis.append(dic) 13 print(lis) 14 f.close()
1 # 3.若改動開頭 第一行 id,name,price,num 以及在裡面增添資料怎麼寫? 2 3 f = open(r"水果.txt",mode="r",encoding="utf-8") 4 title = f.readline().strip() # 讀取第一行 id,name,price,num 5 lis = title.split(",") # 字串分割成列表 [`id`, `name`, `price`, `num`] 6 lis1 = [] 7 for line in f: 8 dic = {} 9 li = line.strip().split(",") 10 for i in range(len(lis)): 11 dic[lis[i]] = li[i] 12 lis1.append(dic) 13 print(lis1) # [{`id`: `1`, `name`: `榴蓮`, `price`: `500`, `num`: `60000`}, {`id`: `2`, `name`: `蘋果`, `price`: `700`, `num`: `70000`}, {`id`: `3`, `name`: `荔枝`, `price`: `600`, `num`: `60000`}, {`id`: `4`, `name`: `西瓜`, `price`: `800`, `num`: `70000`}] 14 f.close() 15 16 17 ``` 18 新增修改資料: 19 序號,名字,價格,數量,倉庫 20 1,榴蓮,500,60000,倉庫01 21 2,蘋果,700,70000,倉庫02 22 3,荔枝,600,60000,倉庫02 23 4,西瓜,800,70000,倉庫03 24 ``` 25 # 再次列印: 26 # [{`序號`: `1`, `名字`: `榴蓮`, `價格`: `500`, `數量`: `60000`, `倉庫`: `倉庫01`}, {`序號`: `2`, `名字`: `蘋果`, `價格`: `700`, `數量`: `70000`, `倉庫`: `倉庫02`}, {`序號`: `3`, `名字`: `荔枝`, `價格`: `600`, `數量`: `60000`, `倉庫`: `倉庫02`}, {`序號`: `4`, `名字`: `西瓜`, `價格`: `800`, `數量`: `70000`, `倉庫`: `倉庫03`}]