第九天- 檔案操作 r w a 檔案複製/修改

剎那燈火明發表於2018-10-26
檔案操作簡介:
使用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`}]

 




  



 

 
 


 

相關文章