python文件操做之二進制

  • 列表項

三元運算符號:

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

文件處理

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

正常的文件如上面的步驟,怎麼用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()沒有打印出來對應的插入的內容,3d

  • 不是每次讀完了,都從新讀,就相似一個光標,光標在開始時候光標在第一個位置,而後read以後光標在最後,而後寫的時候,結果光標又定位在最後了,因此讀的時候從光標的位置日後讀,全部讀出來的結果就是空的,沒有讀出來;code

  • 寫讀模式: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)
相關文章
相關標籤/搜索