目錄html
咱們知道音頻,視頻和圖片在硬盤中也是用二進制存儲的,可是字符編碼只和文本文件有關,所以'utf-8'格式的編碼並不適用視頻,視頻有其自己的編碼格式,如MP四、avi、mkv等。python
文件是操做系統爲用戶或者應用程序提供的一個讀寫硬盤的虛擬文件單位。文件的操做是基於文件,即文件的操做核心就是:讀和寫。macos
就是說只要咱們想要操做文件就是對操做系統發送請求,而後有操做系統將用戶或應用程序 對文件的讀和寫操做轉換成集體的硬盤指令(好比控制盤片的轉動,控制機械手臂的移動,以此來讀取數據。)vim
內存沒法永久保存數據,但凡咱們想要永久保存數據都須要把文件保存在硬盤中,而操做文件就能夠實現對硬件的操做。app
文件的做用:存儲數據編輯器
如今咱們有一個需求須要把用戶輸入的帳號密碼存儲到硬盤中,咱們使用Python該如何操做呢?工具
name = 'chen' pwd = '123'
若是咱們須要打開一個文件,須要向操做系統發起請求,要求操做系統打開文件,佔用操做系統的資源。python中使用open()測試
方法能夠打開某一個具體的文件,open()方法內寫入文件路徑。編碼
open(r'F:\python自學\db.txt')
想想,若是給列表增長值,咱們須要給列表賦值後才能給對應的列表加值,對文件來講也是同樣的。操作系統
lis = [1,2,3] lis.append(4) lis.append(5)
#打開文件 f = open(r'F:\python自學\db.txt') print(f) #輸出: <_io.TextIOWrapper name='F:\\python自學\\db.txt' mode='r' encoding='cp936'>
打開文件後,文件不只佔用了內存,他還對應了操做系統打開的以文件,至關於使用文本編輯器打開了一個文件。而且操控文件只是爲了讀和寫,所以打開文件並非目的,讀和寫纔是目的,接下來咱們嘗試如何讀寫文件。
#read 模式打開文件 f = open(r'F:\python自學\db.txt',mode='r',encoding="utf8") #讀取文件內容,向操做系統發起讀請求,會被操做系統轉成具體的硬盤操做,將內容由硬盤讀入內存。 data = f.read() print(data) # 因爲python的垃圾回收機制只回收引用計數爲0的變量,可是打開文件還佔用操做系統的資源,因此須要收回操做系統的資源 #不能使用del f # del f 只是對變量f 的回收 f.close() #輸出: name,123,1000
相對於當前執行文件所在的文件夾開始找
文件操做的基礎模式由三種(默認的操做模式爲r模式):
文件讀寫內容的格式有倆種(默認的讀寫內容的模式爲b模式):
須要注意的是:t,b這倆種模式均不能單獨使用,都須要與r模式、w模式、a模式之一連用。
r:read,只讀模式,只能讀不能寫,文件不存在時報錯。
f = open('F:\python自學\db.txt',mode='rt',encoding='utf-8') data = f.read() print(data) print(f"type(data):{type(data)}") f.close() #輸出: name,123,1000 type(data):<class 'str'>
# rb:read by bytes f = open('F:\python自學\db.txt',mode='rb') data = f.read() print(data) print(f"type(data):{type(data)}") f.close() #輸出: b'name,123,1000\r\nname,123,1000000000\r\nname,123,100000\r\nchen,456,1222555444556\r\nchen,456,456\r\n' type(data):<class 'bytes'>
f.read()讀取文件指令會跑到文件的末端,若是在一次讀取,讀取的將會是空格。
f = open('F:\python自學\db.txt',mode='rt',encoding='utf-8') data1 = f.read() data2 = f.read() print('data1:',data1) print('data2:',data2) f.close() #輸出: data1: name,123,1000 name,123,1000000000 name,123,100000 chen,456,1222555444556 chen,456,456 data2:
因爲f.read()一次性讀取文件的全部內容,若是文件很是大的 話,可能會形成內存爆掉,即電腦卡死。所以可使用f.readline()或者f.readlines()來讀取文件內容。readline()讀取一行,readlines()讀取多行,而且以列表的形式展示的。
# f.readline()/f.readlines() f = open('F:\python自學\db.txt',mode='rt',encoding='utf-8') data1 = f.readline() data2 = f.readlines() print('data1:',data1) print('data2:',data2) f.close() #輸出: data1: name,123,1000 data2: ['name,123,1000000000\n', 'name,123,100000\n', 'chen,456,1222555444556\n', 'chen,456,456\n']
w:只能寫,不能讀,文件存在的時候會清空文件後在寫入內容;文件不存在的時候會建立文件後寫入內容。
#wt f = open('32w.txt',mode='wt',encoding='utf-8') print('f.readable()',f.readable())# 判斷文件是否可讀 f.write('chenshuaibi\n') f.write('what,厲害') f.write('chen,佩服啊') f.flush()#刷新,馬上將文件內容刷到硬盤 f.close() #輸出: f.readable() False
#wb,編碼成bytes類型 f = open('33w.txt',mode='wb') f.write('chenshuaibi'.encode('unicode_escape')) print("type('chenshuaibi'.encode('unicode_escape'))",type('chenshuaibi\n'.encode('unicode_escape'))) f.close() #輸出: type('chenshuaibi'.encode('unicode_escape')) <class 'bytes'>
a:能夠追加。文件存在,則在文件的末端寫入內容;文件不存在的時候會建立文件後寫入內容。
#at f = open('35a.txt',mode='at',encoding='utf-8') print("f.readable()",f.readable()) f.write('chen真帥') f.close() #輸出: f.readable() False
b模式是通用的模式,由於全部的文件在硬盤中都是以二進制的形式存儲的,須要注意的是:b模式讀寫文件,必定不能加上encoding參數,由於二進制沒法在進行編碼
try: import requests response = requests.get( 'http://www.chenyoude.com/Python從入門到放棄/文件的三種打開模式-mv.jpg?x-oss-process=style/watermark') data = response.content f = open('mv.jpg?x-oss-process=style/watermark', 'wb') f.write(data) print('done...') f.close() except Exception as e: print(e, '報錯了,那就算了吧,之後爬蟲處會詳細介紹')
done...
f = open('34w.txt', 'wb') f.write('nick 好帥啊'.encode('utf8')) f.close()
以前咱們使用open()方法操做文件,可是open打開文件後咱們還須要手動釋放文件對操做系統的佔用,可是其實咱們能夠更方便的打開文件,即python提供的上下文管理工具——with open().
with open('32.txt','rt',encoding='utf-8') as f: print(f.read()) #輸出32.txt內的內容: 大帥逼
with open()方法不只提供自動釋放操做系統佔用的方法,而且with open可使用逗號分隔,一次性打開多個文件,實現文件的快速拷貝。
#建立新文件35r.txt,將32。txt的內容複製 with open('32.txt','rb') as fr,open('35r.txt','wb') as fw: fw.write(fr.read())
#wt with open('36w.txt'.'wt',encoding='utf-8') as fw: print(fw.readable())#檢測是否可讀 #輸出: False # 不能讀取 print(fw.writable())#檢測是否可寫 #輸出: True # 能夠寫
#w+t with open('36.txt','w+t',encoding='utf-8') as fw: print(fw.readable()) #輸出: True #可讀取 print(fw.writable()) #輸出: True # 能夠寫
#r+t with open('36.txt','r+t',encoding='utf-8') as fw: print(fw.readable()) #輸出: True #可讀取 print(fw.writable()) #輸出: True # 能夠寫
假設咱們須要在文件內容中間的某一行增長內容,若是使用基礎的r、w、a模式實現是很是困難的,所以咱們須要多文件內的指針進行移動。
with open('36.txt','r+t',encoding='utf-8') as fr: fr.readline() fr.write('大帥逼')#寫到文件最後一行
硬盤上沒有修改的說法,硬盤上只有覆蓋,即新內容覆蓋原來的內容。
seek(offset,whence):offset表明文件指針的偏移量,單位是字節
# seek(offset,whence) with open('36.txt','rt',encoding='') as fr: print(f"fr.seek(3,0):{fr.seek(3,0)}")#0至關於文件頭開始,1至關於當前文件所在的位置,2至關於文件末尾 #fr.seek(0,2)#切換到文件末尾
tell():每次統計都是從文件開頭到當前指針所在的位置。
#tewll # 計算指針前面有多少字符 with open('36.txt','rt',encoding='utf-8') as fr: fr.seek(4,0) print(fr.tell())
read(n):只有在模式下的read(n),n表明的是字符個數,除此以外,其餘但凡涉及文件指針的都是字節個數。
#read with open('36.txt','rt',encoding='utf-8') as fr: print(fr.read(3))#讀出指針後n位
truncate(n):truncate(n)是截斷文件,因此文件的打開法師必須是可寫,可是不能用w、w+等方式打開,由於那樣直接清空文件的內容了,因此truncate(n)要在r+、a、a+等模式下測試效果。它的參照物永遠是文件頭,而且truncate()若是沒有參數的話,就至關於直接清空文件。
with open('36.txt','r+t',encoding='utf-8') as fr: fr.truncate(3)
文件的數據是存放在於硬盤上的,於是只存在覆蓋,不存在修改的說法,平時咱們看到我修改文件都是模擬出來的效果,具體有倆種方式。
將硬盤中存放在該文件的內容所有加載到內存,在內存中是能夠修改的,修改完畢後,在有=由內存覆蓋到硬盤(word,vim,nodpad++等編輯器)。
import os with open('36.txt') as fr,open('36swap.txt') as fw: data = fr.read() data = data.replace('tank','tankSS')#進行替換修改 fw.write(data)#將信息重新新寫入 #刪除原文件 os.remove('36.txt') #文件重命名 os.rename('36swap.txt','36.txt')
import os with open('36.txt') as fr,open('36swap.txt') as fw: # 循環讀取文件的內容,逐行進行修改 for line in fr: line = line.replace('nick','chen') fw.write(line)寫入修改後的信息 #刪除原文件 os.remove('36.txt') #文件重命名 os.rename('36swap.txt','36.txt')
####10153.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> </body> </html>
read()
with open("10153.html",mode="r",encoding="utf8") as f: data=f.read()#沒有參數,讀取所有 print(data) ################ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> </body> </html>
with open("10153.html",mode="r",encoding="utf8") as f: data=f.read(8)#有參數以後按照字節來讀 print(data) #################### <!DOCTYP
readline()
with open("10153.html",mode="r",encoding="utf8") as f: data=f.readline()#沒有參數讀取一行 print(data) ################# <!DOCTYPE html>
with open("10153.html",mode="r",encoding="utf8") as f: data=f.readline(8)#有參數以後按照字節來讀 print(data) ############### <!DOCTYP
readlines()
with open("10153.html",mode="r",encoding="utf8") as f: data=f.readlines()#沒有參數,返回一個列表,而且一行是一個數據 print(data) #################### ['<!DOCTYPE html>\n', '<html lang="en">\n', '<head>\n', ' <meta charset="UTF-8">\n', ' <title>Title</title>\n', '</head>\n', '<body>\n', '</body>\n', '</html>']
with open("10153.html",mode="r",encoding="utf8") as f: data=f.readlines(33)#有參數的時候,返回列表,而且在參數是字節的長度,只有給我長度大於本行或者前面的全部字節,才能讀到下一行,返回的是列表 print(data) #################### ['<!DOCTYPE html>\n', '<html lang="en">\n', '<head>\n']
write
with open("10152.html", mode="w", encoding="utf8") as f: # f.writable()#清空 # f.writelines(["dd\n","ddcc\n","ll\n"])#寫多行 # f.write("dd") pass