第六章 檔案操作

柠檬の夏天發表於2024-04-29

1.檔案讀寫操作

'''
語法:
fp = open(檔案,模式,編碼集)
fp => 檔案的io物件(檔案控制代碼)
i  => input  輸入
o  => outpur 輸出

fp.read()  讀取檔案內容
fp.write() 寫入檔案的內容
'''

# (1)檔案的寫入操作
fp = open("ceshi1.txt",mode="w",encoding="utf-8")
fp.write("把大象懟進去")
fp.close()


# (2)檔案的讀取操作
fp = open("ceshi1.txt",mode="r",encoding="utf-8")
res = fp.read()
fp.close()
print(res)

2.檔案二進位制讀寫

'''
二進位制位元組流:用於傳輸資料或者儲存資料的一種資料格式
b"abc" b開頭的位元組流要求資料只能是ascii編碼中的字元,不能是中文

# 將字串和位元組流(Bytes流)型別進行轉換(引數寫成轉化的字元編碼格式)
    # encode() 編碼  將字串轉化為位元組流(Bytes流)
    # decode() 解碼  將Bytes流轉化為字串
'''
data = "中文".encode("utf-8")
print(data, type(data))

res = data.decode("utf-8")
print(res,type(res))

# utf-8下 一箇中文佔用3個位元組
data = "中文".encode("utf-8")

# 計算位元組總大小
print(len(data))

# 把"我愛你"這個位元組流進行反解恢復成原來的字元"我愛你"
print("我愛你".encode())
res = b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'.decode()
print(res)


# (1)檔案儲存二進位制的位元組流
'''如果儲存的是二進位制位元組流,指定模式wb,不要指定encoding編碼集,否則報錯'''
fp = open("ceshi2.txt",mode="wb")
strvar = "小明".("utf-8")encode
fp.write(strvar)
fp.close


# (2)檔案讀取二進位制的位元組流
fp = open("ceshi2.txt",mode="rb") 
res = fp.read()
fp.close()
print(res)
print(res.decode())

#(3)檔案複製
'''所有的圖片,音訊,影片都需要透過二進位制位元組流來進行儲存傳輸'''
# 先把原檔案的二進位制位元組流讀取出來
fp = open(r"D:\tmp\code\day06\集合.png",mode="rb")
res = fp.read()
fp.close()

# 計算檔案中的位元組個數 => 檔案大小
print(len(res))

# 再把二進位制位元組流寫入到另一個檔案中,相當於複製
fp = open("集合2.png",mode = "wb")
fp.write(res)
fp.close()

3.檔案操作的擴充套件模式

"""
# (utf-8編碼格式下 預設一箇中文三個位元組)
    # read()   功能:讀取字元的個數(裡面的引數代表字元個數)
        注意:從當前游標往右邊讀
    # seek()  功能:讀取字元的個數(裡面的引數代表字元個數)
        seek(0)  把游標移動到0位元組的位置上
        seek(0,2) 把游標移動到檔案的末尾
    # tell()      功能:當前游標左側所有的位元組數(返回位元組數)
    
"""

# (1) r+ 先讀後寫
fp = open("ceshi4.txt",mode= "r+",encode="utf-8")
# 先讀
res = fp.read()

# 再寫
fp.write("ab")
# 再讀
fp.seek(0) # 透過seek把游標移動到開頭
print(fp.read())
fp.close()


#(2)r+ 先寫後讀
fp = open("ceshi3.txt",mode="r+",encoding="utf-8")

# 移動游標到最後,否則r模式下,原字元會被覆蓋
fp.seek(0,2)
# 先寫
fp.write("cd")

# 把游標移動到檔案的開頭
fp.seek(0)
# 再讀
res = fp.read()
print(res)
fp.close()


#(3)w+ 可讀可寫
fp = open("ceshi4.txt",mode="w+",encoding+"utf-8")
fp.write("abc)
fp.seek(0)
print(fp.read())
fp.close()


#(4)a+ 可讀可寫,追加寫入(預設可以建立新的檔案)
fp = open("ceshi5.txt",mode="a+",encoding="utf-8")
fp.write("def")
# 讀內容
fp.seek(0)
print(fp.read())
fp.close


#(5).seek,tell,read之間的使用
'''
r+模式基於當前游標所在的位置進行寫入覆蓋
a+模式會強制把游標放到檔案末尾進行追加寫入
'''
fp = open("ceshi5.txt",mode=a+"",encoding="utf-8")
fp = open("ceshi5.txt",mode="a+",encoding="utf-8")
fp.seek(3) # 從頭數3個位元組的位置
# fp.write("zxc") #模式會強制把游標放到檔案末尾進行追加寫入
print(fp.read())
fp.close()



#(6)seek,tell,read之間的使用
fp = open("ceshi5.txt",mode="r+".encoding="utf-8")
fp.seek(4)

# tell 當前游標左邊所有內容的位元組數
res = fp.tell()
print(res)


# 在r+模式下read(2)代表讀取2個字元 在rb模式下read(2)代表讀取2個位元組
fp.read(2) # 當前游標往右所有的字元內容
print(fp.tell())
fp.close()


#(7)注意點(seef在移動時,又可能移動到某個漢字的位元組中間,導致原位元組無法解析)
fp = open("ceshi6.txt",mode="r+",encoding="utf-8")
fp.seek(3)
print(fp.read())
fp.close()
print("你".encode())


#(8)with 自動實現關閉檔案操作
# 方法一:讀取二進位制位元組流
with open=("集合2.png",mode="rb") as fp:
        res = fp.read()



with open=("集合2.png",mode="wb") as fp:
        res = fp.write(res)
        
   
# 方法二:繼續簡寫
with open=("集合2.png",mode="rb") as fp1,with open=("集合2.png",mode="wb") as fp2:
    res = fp1.read()
    fp2.write(res)


"""
# 重新整理緩衝區 f1ush
    # 當檔案關閉的時候自動重新整理緩衝中區
    # 當整個程式執行結束的時候自動重新整理緩衝區
    # 當緩衝區寫滿了會自動重新整理緩衝區
    # 手動刷緩衝區
"""
open("ceshi1.txt",mode="w",encoding="utf-8")
fp.write("abc")

# 手動重新整理緩衝區,直接把內容寫入到檔案
while True:

    pass

fp.close()

4.檔案相關函式

"""fp這個物件本身是迭代器,可以把檔案中的內容按照換行一行一行遍歷出來"""
fp = open("ceshi1.txt",mode="r",encoding="utf-8")
# readable() 功能:判斷檔案物件是否可讀
print(fp.readable())
# writable() 功能::判斷檔案物件是否可寫
print(fp.writable())


# 遍歷fp檔案物件
for i in fp:
    print(i)
    
   
# 1.readline() 功能:讀取一行檔案內容



# (1)一次把所有內容都讀取出來
 with open("ceshi1.txt",mode="r",encoding="utf-8") as fp:  
        #先讀取一行
        res = fp.readline()
        # 判讀是不是空,不是空在迴圈
        while res:
            print(res)
            # 在讀取一行,放到迴圈中判斷
        res = fp.readline()


        
# (2)注意點:readline(讀取的字元數)  
with open("ceshi1.txt","mode"="r",encoding="utf-8") as fp:
        """
        讀取的字元數量>實際當前字元數量的時候 => 按照當前行讀取
        讀取的字元數量 <實際當前字元數量的時候=> 按照實際數量來讀
        """
        res = fp.readline(300)
        print(res)
        
        
        
 
# 2.readlines() 功能:將檔案中的內容按照換行讀取到列表當中
lst_new = []
with open("ceshi1.txt",mode="r+",encoding="utf-8") as fp:
    list = fp.readlines()
    for i in lst:
        lst.new.append(i.strip())
               
print(lst_new)




# 3.writelines()  功能:將內容是字串的可迭代性資料寫入檔案 引數:內容為字串型別
lst = ["床前明月光","疑是地上霜","舉頭望明月","低頭思故鄉"]
with open("ceshi2.txt",mode="w+",encoding="utf-8"):
        fp.writelines(lst)
        
# ### 實現效果:加入換行效果,並且插入一句話:alex你真帥呀,插在低頭想家鄉的前面
lst_new = []
# 先把內容插入到原列表中
lst.insert(-1"alex你真帥呀")
# 迴圈原列表,把每一個元素拼接\n, 放到新列表
for i in lst:
    lst_new.append(i + "\n")
print(lst_new)
# 把新列表中的每行內容插入到檔案中
with open("ceshi2.txt",mode="w+",encoding="utf-8") as fp:
        fp.writelines(lst_new)
        


# 注意點:內容必須是字串,不能是整型
lst = [1,2,3]
with open("ceshi2.txt",mode="w+",encoding="utf-8") as fp:
    fp.writelines(lst)
    

# truncate() 功能:把要擷取的字串提取出來,然後清空內容將提取的字串重新寫入檔案
with open("ceshi2.txt",mode="r+",encoding+"utf-8") as fp:
        fp.truncate(3)
        


"""
seek(位元組)
truncate(位元組)
read(字元/位元組)
readline(字元/位元組)
"""