python文件操作之二進制


  • 列表項

三元運算符號:

a=3
b=7
val=a if a>b else val=b
print(val)

文件處理

首先給你一個文件,或者自己建立一個文件,那如何查看文件的內容呢?
1.安裝個文本編輯器
2.選中右鍵,利用文本編輯器軟件打開
3.查看OR寫入
4.保存關閉

正常的文件如上面的步驟,怎么用Python打開這個文件,修改刪除

1.怎么樣用Python讀一個文件;(自己在桌面建了一個文件叫test123)

f =open(file='D:/Users/tufengchao/Desktop/test123',mode='r',encoding='utf-8')
data = f.read()
f.close()
  • file是路徑
  • mode 是打開的模式,r-讀,w-寫,rb-二進制
  • encoding 編碼格式
  • read() 是讀一個文件
  • close()是讀了一個文件然后關閉

  • 這里解釋一下這個問題,首先我們的文件在硬盤里面是以二進制存儲格式,最終讀到內存是不是要轉換我們能看懂的東西,從二進制轉化為我們能看懂的內容,是有個對應的關系的,是按照字符編碼來的,這個文件是按照gbk存儲的,結果讀的時候是按照utf-8來讀的,所以在對應的編碼表里面找不到對應的關系;
  • 我們平時使用的Word,也是這樣的,只是微軟幫你轉換好了,小白用戶是看不到這里面的轉換的,直接使用就OK了
  • 在Python里面,你一定要記住你自己的文檔是什么格式的,讀的時候用什么格式的讀,你要告訴Python你之前的是什么格式,要以什么格式打開,如果不指定,Python3默認的編碼格式就是utf-8,(只要出現上述的報錯,就是編碼格式錯誤);
  • 如果不知道自己的文件原來的編碼格式可以使用pycharm打開,pycharm右下角會自動給你檢測的;

文件處理二進制模式:

python3里面所有的字符都是utf-8的形式,如果在打開一個文件的時候我不知道這個編碼怎么辦?

那我們就不指定encoding的編碼,那么Python3默認就是utf8但是這樣也不行,同時我們要改變讀的模式,才可以,r就是文本模式,可以直接讀取字符串的,如果用戶不知道文件的格式的話可以不指定編碼格式,同時直接使用rb的模式,就是硬盤怎么存儲的你就怎么存到內存,直接以二進制的形式,就可以了;

f=open(file='D:/Users/tufengchao/Desktop/test123',mode='r',encoding='utf-8')
data=f.read()
print(data)
  • 如上述我指定了編碼格式會報錯:binary mode doesn't take an encoding argument
f=open(file='D:/Users/tufengchao/Desktop/test123',mode='r',)
data=f.read()
print(data)
  • 以上則不會報錯
  • 基本二進制就是不給人家看的,例如視頻的格式,等等就是二進制的;
  • 基本來說 rb的模式就是不給人看的,就是網絡傳輸用的,硬盤里面存的是什么讀出來的就是什么;

以上如果用戶就是想看呢,怎么辦呢?二進制的傳來傳去的最終有人會使用這個文件的,不管什么文件傳來傳去如果記不得什么格式怎么辦呢?

  • 問題:在傳輸的時候對方不知道是以什么格式傳給用戶,傳來傳去彼此都忘了什么格式:
在編碼的時候:utf8:是3個字符,gbk是2個字符,每個字符數字對應的字符,一段2進制串,如果10個字節全部都是中文,永遠不能是utf-8,但是又要存成中文,就只能是gbk了,第三方的工具箱,會自動檢測這段文字是什么編碼。
我們需要用到一個第三方的工具包叫:**chardet**

教大家如何安裝chardet

  • pip3 install chardet
  • 然后代碼輸入:
import chardet
f= open('log',mode='rb')
data=f.read()
f.close()
result=chardet.detect(open('log',mode='rb').read())
print(result)
  • 通過上述我們可以知道什么的編碼了,然后就可以通過具體的編碼來看了;** 備注 **以上文件的路勁都是自己的本地,如果需要練習,大家可以自己創造文件;

文件處理寫模式操作文件:

  • 如果文件特別大,一read就全部讀出來,如果內存小怎么辦?
    1.可以不可以每次讀一點,然后丟掉一點,然后在讀一點?答案是當然可以了
f=open('D:/Users/tufengchao/Desktop/test123','r',encoding='utf-8')
for line in f:
    print(line)
f.close()

  • 如上述的代碼執行的結果中,竟然每行下邊會有空格,為什么會有空格呢?
    1.因為prit本身就會換行;如上述的代碼換成:
f=open('D:/Users/tufengchao/Desktop/test123','r',encoding='utf-8')
data=f.read()
print(data)

就不會有問題了,
如果是:

for line in f:
    print(line)

就會換行

寫文件:

f=open('D:/Users/tufengchao/Desktop/test123','w',encoding='utf-8')
f.write('老北京科技大學,微信號:xxx')
f.close()

如上述就是寫的格式,(備注:文件可以自行准備,寫的內容可以自己寫入,同時這里面的編碼要根據你要編寫的文件的編碼格式,並不是所有文件都是utf8,有可能是gbk等等)

f=open('D:/Users/tufengchao/Desktop/test123','wb')
f.write('第二夢')
print(f.read())

會發現,之間的文件內容,現在只有:“第二夢”了
w不是修改,是創建了一個新的文件名字,如果和原來的舊文件有名字一樣,原來的文件就是清空,如果是文件名字不一樣就是新建,所以我們要是小心使用:w

追加模式

  • 如果對一個文件我要修改一個條,或者追加一個內容:
f=open('D:/Users/tufengchao/Desktop/test','a',encoding='utf-8')
f.write('我要追加哈哈!!!!')
f.close()
  • 注意:文件操作的時候,以 “a” 或者“ab”模式打開,則只能追加,即:在原來的內容尾部追加內容
  • 寫入硬盤時候,必須是:0101010101,打開時候需要注意:
  • ab,寫入時,需要直接傳入以某種編碼的010101010 ,即:字節類型
  • a 和encoding 寫入時需要傳入Unicode字符串,內部會根據encoding制定的編碼將Unicode字符串轉換為該編碼的01001010101

讀寫混合模式

  • r+ 就是讀寫混合模式:
f=open('D:/Users/tufengchao/Desktop/test','r+',encoding='utf-8')
data=f.read()
print(data)
f.write('混合模式啦!!!!')
data1=f.read()
print(data1)
f.close()
  • 注意上述的第二個,read()沒有打印出來對應的插入的內容,

  • 不是每次讀完了,都重新讀,就類似一個光標,光標在開始時候光標在第一個位置,然后read之后光標在最后,然后寫的時候,結果光標又定位在最后了,所以讀的時候從光標的位置往后讀,所有讀出來的結果就是空的,沒有讀出來;

  • 寫讀模式:w +

  • 讀寫和寫讀 聽上去是一樣的,其實完全不一樣,讀寫模式:先讀寫,寫讀:是寫模式打開,是寫打開寫,然后在讀;(寫:可以把原來的覆蓋掉的)

  • w+基本上應用場景比較少;

文件操作的其他的基本功能:

def fileno(self,args,**kwargs):返回文件句柄在內核中的索引值,以后做IO多路復用的時候可以用到;
def flush(self ,
args,**kwargs):把文件從內存buffer里面強制刷新到硬盤上,例如:

f=("f_flush_test.txt",'w')
f.write("\ntest")
  • 這時候打開文件f_flush_test.txt,發現是空白的:why?
  • 主要是寫入的內容會先存入內存,然后在從內容寫入硬盤,因為存入內存要比寫入硬盤快很多;
  • 如上述的代碼后邊加入:f.close()就可以在文件f_flush_test.txt這個文件里面看到了;so每寫一個字符都要往硬盤里面寫的話會讓速度很慢,所以就搞了個緩存功能,buffer,這個是可以改的,滿了就會刷到硬盤里面,
    1.如果數據特別的大,但是有突然斷電了這個怎么辦呢?
    2.默認是buffer滿了自動刷,現在要求強制刷,有沒有這么的功能呢?
f=("f_flush_test.txt",'w')
f.write("\ntest")
f.flush()

3.這時候打開文件是不是就有了剛才寫的內容了;

def readable(self ,args ,**kwargs):判斷是否可讀
def readline(self ,
args,kwargs):只讀一行,遇到\r or \n為止
def seek(self ,*args ,
kwargs):
把文件的光標移動到制定的位置;

  • 注意:seek的長度是按照字節算的,字符編碼存每個字符所占的字節長度不一樣。
  • 如:我愛祖國,用gbk存就是2個字節,用utf-8存就是3個字節,因此以gbk打開時,seek(4)光標就會定位在“愛”之后
  • 如果是utf-8,seek(4)會導致,拿到“愛”這個字的一部分字節,打印的話會報錯,因此處理剩下的文本時發現用
  • def seekabale(self,*args,**kwargs)判斷文件是否可以進行seek操作
  • def tell(self,*args,**kwargs)返回當前文件操作的光標位置
  • read()是按照字符來讀的,tell()和seek()是按照字節來的
  • def truncate(self,*args,**kwargs)按照指定的長度截取文件
  • def writable(self,*args,**kwargs)判斷是否可以寫
  • word 在讀取大文件的時候會慢,是因為他把硬盤的文件全部讀取到內存,然后在內存中進行增刪改查,在內存中就可以隨便的修改了,就像列表一樣,可以隨意的修改東西;
  • 文件特別的大,會不會內存爆掉呀?
  • 有沒有即不爆掉內存,又可以存到內存,我可以邊讀邊修改,先讀出來一點,然后檢測一下是否修改,如果修改,就修改了放到新文件,如果不修改,就直接放到新文件里面,從一邊讀往一邊寫,這樣就不會占內存了,就多站點硬盤;
f_name='f_test.txt'
f_new_name ='%s.new' %f_name
old_str='wo'
new_str='haha'
f=open(f_name,"r",encoding='utf8')
f_new =open(f_new_name,"w",encoding='utf-8')
for line in f:
    if old_str in line:
        line=line.replace(old_str,new_str)
    f_new.write(line)
f.close()
f_new.write(line)
f.close()
f_new.close()
os.rename(f_new_name,f_name)


免責聲明!

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



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