python3 文件操作


'''
一、文件操作(讀寫追加,其他方法)
f = open(文件,mode="模式", encoding="編碼")
模式:
    r:只讀
    w:只寫
    a:追加寫
    +:擴展
    b:字節(非文本文件)

讀取文件最好的方案
with open() as f:
    for line in f:
        line = line.strip()

修改文件:
1、創建一個文件副本。
2、把源文件中的內容讀取到內存。
3、然后再內存中進行修改。
4、修改之后保存在文件副本中。
5、把源文件刪除。
6、把文件副本更改名稱為源文件的名稱。

1.1.初識文件操作
    使用python來讀寫文件是非常簡單的操作。我們使用open()函數來打開一個文件,獲取到文件句柄。
然后通過文件句柄就可以進行各種各樣的操作了。根據打開方式的不同能夠執行的操作也會有相應的差異。
打開文件的方式:r, w, a, r+, w+, a+, rb, wb, ab, r+b, w+b, a+b默認使用的是r(只讀)模式

1.2.只讀操作(r, rb)
需要注意encoding表示編碼,根據文件的實際保存編碼進行獲取數據,對於我們而言,更多的是utf-8.
'''
'''1.寫模式(w, wb)
寫的時候注意,如果沒有文件,則會創建文件,如果文件存在,則將原件中原來的內容刪除,再寫入新內容'''
f = open("a1.txt", "w", encoding="utf-8")
f.write("蘋果\n")
f.write("桃子\n")
f.write("香蕉\n")
f.close()
'''w只讀write模式,寫會報錯'''
f = open("a1.txt", "w", encoding="utf-8")
f.write("蘋果\n")
f.write("桃子\n")
f.write("香蕉\n")
content = f.read()  # UnsupportedOperation: not readable
f.close()
---------------------------------------------------------------------------
UnsupportedOperation Traceback (most recent call last) <ipython-input-129-01a25d1ab733> in <module>()  4 f.write("桃子\n")  5 f.write("香蕉\n") ----> 6 content = f.read() # UnsupportedOperation: not readable  7 f.close() UnsupportedOperation: not readable

'''
wb模式下,不指定打開文件的編碼,但是在寫文件的時候必須將字符串轉換成utf-8的bytes數據。
'''
f = open("c1.txt", mode="wb") 
print("橙汁".encode("utf-8"))  # b'\xe6\xa9\x99\xe6\xb1\x81'
f.write("橙汁".encode("utf-8"))
f.flush()
f.close()
b'\xe6\xa9\x99\xe6\xb1\x81'

'''
2.r只讀read模式,read()將文件中的內容全部讀取出來,弊端:占內存,如果文件過大。容易導致內存崩潰。
'''
f = open("a1.txt", mode="r", encoding="utf-8")
content = f.read()
print(content)
f.close()
蘋果
桃子
香蕉
'''r只讀read模式,寫會報錯'''
f = open("a1.txt", mode="r", encoding="utf-8")
content = f.read()
print(content)
f.write("aaa")  # UnsupportedOperation: not writable
f.close()
蘋果
桃子
香蕉

---------------------------------------------------------------------------
UnsupportedOperation Traceback (most recent call last) <ipython-input-132-1bb711d148ec> in <module>()  3 content = f.read()  4 print(content) ----> 5 f.write("aaa") # UnsupportedOperation: not writable  6 f.close() UnsupportedOperation: not writable 
'''
rb讀取出來的數據是bytes類型,在rb模式下,不能選擇encoding字符集。
rb的作用:在讀取非文本文件的時候,比如讀取MP3、圖像、視頻、直播等信息的時候就需要用到rb。因為這種數據是沒辦法直接顯示出來的。
在后面我們文件上傳下載的時候還會用到。
'''
f = open("a1.txt", "rb")
content = f.read()  # read一次把文件內容讀取完,type類型
print(content)  # utf-8編碼下,一個漢字是3個字節,一個字節是8位,gbk編碼下,一個漢字是2個字節
f.close()
b'\xe8\x8b\xb9\xe6\x9e\x9c\r\n\xe6\xa1\x83\xe5\xad\x90\r\n\xe9\xa6\x99\xe8\x95\x89\r\n'
'''
read(n)讀取n個字符。需要注意的是,如果每次讀取,那么會在當前位置繼續去讀取而不是從頭讀。
如果使用的是rb模式,則讀取出來的是n個字節。
'''
f = open("a1.txt", mode="r", encoding="utf-8")
content = f.read(4)  # 4個字符
print(content)
f.close()
蘋果
桃
'''
readline()一次讀取一行數據,注意:readline()結尾,注意每次讀取出來的數據都會有一個\n,需要我們使用strip()方法來去掉\n或者空格。
'''
f = open("a1.txt", mode="r", encoding="utf-8")
content = f.readline()  # 讀取一行
print(content)
content2 = f.readline()  # 讀取一行
print(content2)
content3 = f.readline()  # 讀取一行
print(content3)
f.close()
蘋果

桃子

香蕉
'''
readlines()將每一行形成一個元素,放到一個列表中。將所有的內容都讀取出來,容易出現內存崩潰的問題,不推薦使用。
'''
f = open("a1.txt", mode="r", encoding="utf-8")
lst = f.readlines()  # 一次把文件讀取完,每行為一個元素,放入列表中
print(lst)  # ['蘋果\n', '桃子\n', '香蕉']
for line in lst:
    print(line.strip())
f.close()
['蘋果\n', '桃子\n', '香蕉\n']
蘋果
桃子
香蕉
'''
for循環讀取,這種方式是最好的,每次讀取一行內容,不會產生內存溢出的問題。
'''
f = open("a1.txt", mode="r", encoding="utf-8")
for line in f:  # 節省內存,一行一行讀取
    print(line.strip())
f.close()
蘋果
桃子
香蕉
'''
3.追加(a, ab)
只要是a、ab、a+都是在文件的末尾寫入,不論光標在任何位置。
在追加模式下,我們寫入的內容會追加在文件的結尾。
'''
f = open("a1.txt", mode="a", encoding="utf-8")
f.write("南果梨")
f.flush()
f.close()
'''ab和wb追加寫和只寫模式的時候,記得編碼后再寫入'''
f = open("a1.txt", mode="ab")
f.write("天山雪蓮".encode("utf-8"))
f.flush()
f.close()
'''
4.讀寫模式(r+, r+b)
對於讀寫模式,必須是先讀,因為默認光標是在開頭的。當讀完了之后再進行寫入,我以后使用頻率最高的模式是r+
正確操作:
'''
f = open("a1.txt", mode="r+", encoding="utf-8")
content = f.read()
print(content)
f.close()
蘋果
桃子
香蕉
南果梨天山雪蓮
'''r+先讀取,光標移動到最后,再寫入,寫入的內容是在最后,然后把光標移動到開始的位置,重新讀取'''
f = open("a1.txt", mode="r+", encoding="utf-8")
f.read()
f.write("讀完了寫入\n")
f.seek(0)
content = f.read()
print(content)
f.close()
蘋果
桃子
香蕉
南果梨天山雪蓮讀完了寫入
'''r+必須是先讀,后寫,容易出現字符編碼問題,會遇到下面的報錯'''
f = open("a1.txt", mode="r+", encoding="utf-8")
f.write("先寫。")  
now_seek = f.tell()
print(now_seek)
f.seek(0)
content = f.read()  # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 9: invalid start byte
print(content)
f.close()
9
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last) <ipython-input-141-3dd82e9e1e9a> in <module>()  5 print(now_seek)  6 f.seek(0) ----> 7 content = f.read() # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 9: invalid start byte  8 print(content)  9 f.close() ~\Anaconda3\lib\codecs.py in decode(self, input, final)  319 # decode input (taking the buffer into account)  320 data = self.buffer + input --> 321 (result, consumed) = self._buffer_decode(data, self.errors, final)  322 # keep undecoded input until the next call  323 self.buffer = data[consumed:] UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa1 in position 9: invalid start byte
'''1.寫模式(w, wb)
寫的時候注意,如果沒有文件,則會創建文件,如果文件存在,則將原件中原來的內容刪除,再寫入新內容'''
f = open("a1.txt", "w", encoding="utf-8")
f.write("蘋果\n")
f.write("桃子\n")
f.write("香蕉\n")
f.close()
'''
錯誤操作:
結果:將開頭的內容改成了“石榴”,然后讀取的內容是后面的內容。
所以記住:r+模式下,必須是先讀取,然后再寫入
'''
f = open("a1.txt", mode="r+", encoding="utf-8")
f.write("石榴")
f.seek(0)
content = f.read()
print(content)
f.flush()
f.close()
石榴
桃子
香蕉
'''
seek(n)光標移動到n的位置,注意,移動的單位是byte。所以如果是UTF-8的中文部分要是3的倍數。
通常我們使用seek都是移動到開頭或者結尾。
移動到開頭:seek(0)
移動到結尾:seek(0, 2) seek的第二個參數表示的是從哪個位置進行偏移,默認是0,表示開頭,1表示當前位置,2表示結尾。
'''
f = open("a1.txt", mode="r+", encoding="utf-8")
f.seek(0)  # 光標移動到開頭,此行可有可無
content = f.read()  # 讀取內容,此時光標移動到結尾
print(f"content: {content}\n")
f.seek(0)  # 再次將光標移動到開頭
content2 = f.read()
print(f"content2: {content2}\n")
f.seek(0, 2)  # 將光標移動到結尾
content3 = f.read()  # 讀取內容,什么都沒有
print(f"content3: {content3}\n")
f.seek(0)  # 移動到開頭
f.write("蘋果")  # 寫入信息,此時光標在6 中文2*3 = 6
f.flush()
f.close()
content: 石榴
桃子
香蕉


content2: 石榴
桃子
香蕉


content3: 
'''
tell()可以幫我們獲取到當前光標在什么位置
'''
f = open("a1.txt", mode="r+", encoding="utf-8")
f.seek(0)  # 光標移動到開頭
content = f.read()  # 讀取內容,此時光標移動到結尾
print(content)
f.seek(0)  # 再次將光標移動到開頭
f.seek(0, 2)  # 將光標移動到結尾
content2 = f.read()  # 讀取內容,什么都沒有
print(content2)
f.seek(0)  # 移動到開頭
f.write("榴蓮")  # 寫入信息,此時光標在6 中文3*2 = 6
print(f.tell())  # 光標的位置6
f.flush()
f.close()
蘋果
桃子
香蕉


6
'''
truncate()截斷文件
'''
f = open("d1.txt", mode="w", encoding="utf-8")
f.write("蘋果")  # 寫入兩個字符
f.seek(3)  # 光標移動到3,也就是兩個字中間
f.truncate()  # 刪除光標后面的所有內容
f.close()
'''
總結:
f.read(n) 如果是r模式打開,表示讀取n個字符
f.read(n) 如果是rb模式打開,表示讀取n個字節
f.seek(n) 表示n個字節,1中文由3個字節組成 
'''
'''a+模式,不管光標移動到哪個位置,都是在最后寫入內容'''
f = open("a1.txt", "a+", encoding="utf-8")
f.seek(0)
f.write("開始位置\n")
f.seek(0)
content = f.read()
print(content)
f.close()
榴蓮
桃子
香蕉
開始位置
'''
修改文件以及另一種打開文件的方式(重點)
文件修改:只能將文件中的內容讀取到內存中,將信息修改完畢,然后將源文件刪除,將新文件的名字改成老文件的名字。
'''
import os

with open("b1.txt", mode="r", encoding="utf-8") as f1,\
    open("b1.txt_temp", mode="w", encoding="utf-8") as f2:
    for line in f1:
        new_line = line.replace("碭山梨", "橙汁")
        f2.write(new_line)
os.remove("b1.txt")  # 刪除源文件
os.rename("b1.txt_temp", "b1.txt")  # 重命名新文件
 
            
import requests


url = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2241880857,977619289&fm=26&gp=0.jpg"
content = requests.get(url).content
with open("flower.jpg", "wb") as f:  # 將圖片寫入文件
    f.write(content)

 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM