python--文件流讀寫


在講述fileinput模塊之前,首先說一下python內置的文件API—open()函數以及與其相關的函數。

我這里主要講講其中四個比較重要和常用的方法,更多的方法,可以參考:菜鳥教程http://www.runoob.com/python/file-methods.html

        

(1)file = open(file_name [, access_mode][, buffering])

參數解析:

1. file_name:

file_name變量是一個需要訪問的文件名稱的字符串值,在應用中需要用單引號或者雙引號將文件名包裹起來。

 

2. access_mode:

access_mode決定了打開文件的模式:只讀,寫入,追加等。這個參數是非強制的,默認文件訪問模式為只讀(r)

詳細模式可以參考:菜鳥教程http://www.runoob.com/python/python-files-io.html

 

3. buffering:

這個參數用於設置緩存區的大小。如果buffering的值被設為0,就不會有緩存。如果buffering的值取1,訪問文件時會寄存行。如果將buffering的值設為大於1的整數,這個整數就為緩存區的緩存大小。如果取負值,寄存區的緩沖大小則為系統默認。

 

(2)file.flush()方法

用於刷新緩沖區,,即將緩沖區中的數據立刻寫入文件,同時清空緩沖區

flush()方法在爬蟲中也用得挺多,在爬蟲過程由於種種原因,程序中斷,寫入緩存的數據沒有寫入磁盤很可惜,所以可以手動添加flush()方法

 

(3)file.close()方法

關閉文件,並將緩沖區的數據寫入文件中。

 

文件的緩存機制

在寫入文件內容的時候,在我們調用python的write()函數對文件進行寫入的時候,python解析器會調用操作系統的write方法,但值得注意的是,不是馬上保存到磁盤中的,是先寫到內核的緩沖區里面,只有當我們主動調用flush()函數或者close()函數的時候,才會將緩沖區的內容寫入磁盤中。另外當寫入的數據量大於或者等於緩沖區的大小的時候,寫緩沖會自動同步到磁盤。

例如:

寫20萬行數據結果

file = open('file1.txt','a+')
for i in range(200000):
    file.write('this line is line%s'%i)
file.write('\r\n')

pycharm報出如下的提示

 

因為我設置的buffering是默認的系統的緩存大小,所以當寫到1999856行時,就剛好到系統的緩存區大小,因為所需要寫的數據大於緩存區的大小,所以這些內容直接就寫入了磁盤,而1998856后面的數據在寫入的時候還是先寫到了緩存區中,而這些數據的大小顯然是小於緩存區大小的,所以被保存在緩存區中,並沒有寫到磁盤。

 

使用flush()方法后,所有在緩存區的數據都會寫入到磁盤中

 

如果我直接在調用open()方法的時候像下面這樣設置buffering為1,就無需擔心緩存的問題了

 

(4)file.seek(offset [,whence])  文件指針

當文件進行寫入或者讀取的時候,文件指針會根據具體的內容進行移動。靈活地運用seek()方法,可以在一次I/O操作中對文件同時進行寫和讀操作,避免多次的I/O。

參數解析:

offset:偏移量,代表需要移動偏移的字節數

whence:可選參數,默認值為 0。作用是給offset參數設定起始值,表示要從哪個位置開始偏移。0代表從文件開頭開始算起,1代表從當前位置開始算起,2代表從文件末尾算起。

例如以下案例:

file = open('file.txt','a+',1)
for i in range(200):
    file.write('this line is line%s'%i)
    file.write('\r\n')

for line in file:
    print(line)

file.close()

終端沒有打印任何數據

 

如果將代碼順序修改一下

file = open('file.txt','a+',1)
for i in range(200):
    file.write('this line is line%s'%i)
    file.write('\r\n')
file.close()

f = open('file.txt','r+')
for line in f:
    print(line)
f.close()

終端打印出數據

那么怎么用seek()方法呢?

import os
file = open('file.txt','a+',1)
for i in range(200):
    file.write('this line is line%s'%i)
    file.write('\r\n')
    file.seek(0,os.SEEK_SET)
    for line in file:
        print(line)
file.close()

同樣也能打印出數據

上面,我用了os模塊的SEEK_SET

os模塊有這些內容:

 os.SEEK_SET:表示文件的相對起始位置

   os.SEEK_CUR:表示文件的相對當前位置

 os.SEEK_END:表示文件的相對結束位置

 

關於fileinput模塊

fileinput可以對文件進行細致化的處理,比直接的open方法有更多文件操擴展。可以一次性迭代一個或者多個文件,並對文件進行修改。

 

主要的函數有:

1. input([files[,inplace[,backup]]]) 幫助迭代多個輸入流中的行

2. filename()  返回當前文件的名稱

3.nestfile()   關閉當前文件並移動到下一個文件

4. close()     關閉序列(多個文件

5. lineno()    返回(多個文件累計的)當前行號

6. filelineno()  返回在當前文件的行好

7. isfirstline()  檢查當前是否是當前文件中的第一行

8. isstdin()     檢查最后一行是否來自sys.stdin

 

可以理解,fileinput模塊重點是對多文件的讀取和適當時候的修改。而沒有直接的寫操作

 

1. input()方法

這個函數是fileinput模塊中最重要的一個函數,參數相對復雜一點。

官方的定義:

fileinput.input([files[, inplace[, backup[, bufsize[, mode[, openhook]]]]]])

input(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None)

1)files列表,可以是一個文件,也可以是多個文件的列表形式

2)inplace  是否對文件進行就地修改。默認為False,設置為False跟文件的open區別不大

3)mode  讀取的格式

官方:FileInput opening mode must be one of 'r', 'rU', 'U' and 'rb'  (b:二進制字節模式和U:unicode模式)

4)backup  文件備份,為原本的文件做一份備份,不作任何修改,其實就是復制。備份的文件名是原本的文件名+備份文件名。注意備份文件需要把文件的格式也寫進去。一般backup需要與參數inplace一起使用才有意義。而在設置了inplace=True,一般同時會設置backup參數來備份原本的文件內容。

 

 

例子:在每一行文本的前面添加 ‘#行號’字樣

單個文件案例:

for line in fileinput.input('file.txt',inplace=True,mode='r',backup='file_back.txt'):
    num = fileinput.filelineno()
    print('#%s'%num+' '+line)

如果inplace設置為True,即就地修改,必須要有print函數將讀取的數據重新寫回當前的文件中,否則文件的數據最后會變成空。所以使用inplace時候必須很小心。

備份后的文件目錄

 

多個文件案例
for line in fileinput.input(files=['file.txt','file1.txt'],inplace=True,mode='r',backup='file_back.txt'):
num = fileinput.filelineno()
print('#%s'%num+' '+line

 

 

通常fileinput模塊會結合re模塊一起使用,例如在對日志的分析中會很有用

例如,這里有一個monoodb的log文件內容

希望獲取日期為11-13的日志

import fileinput
import re
for line in fileinput.input('mongolog.txt',mode='r',inplace=True,backup='log_backup.txt'):
    pattern = '2018-11-13'
    if re.search(pattern,line):
      print(line)

獲取結果在原log.txt文件中,備份文件中的內容與原文件相同

 


免責聲明!

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



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