文件讀寫屬於一種常見的IO操做,因爲操做系統將底層操做磁盤的接口向上封裝爲一種通用接口,所以Python中讀寫文件的基本方法和JAVA、PHP等高級編程語言同樣,先請求操做系統打開一個文件描述符,經過操做系統提供的接口從這個文件對象中讀取數據,或者把數據寫入這個文件中,最後當文件讀寫操做完成後關閉文件。python
須要注意的是文件讀寫完成後必須及時關閉文件,一方面打開的文件會佔用操做系統的資源,而且操做系統同一時間能打開的文件數量也是有限制的,好比Linux操做系統中咱們可使用ulimit -n命令查看最多可打開文件的數量。另外一方面在寫文件時,操做系統是把數據放到內存緩衝區異步寫入磁盤中,並不會馬上把數據所有寫入磁盤,而調用close()方法可使操做系統把沒有寫入磁盤的數據所有寫入磁盤中,防止數據丟失的狀況。接下來咱們先看下正確的文件打開方式。編程
文件打開的幾種方式緩存
Python內置了open()方法打開了一個文件,以下所示。文件打開模式有'r'、'w'、'a'、'r+'、'w+'、'a+'、'b'等,'r'只讀模式打開文件,並將文件指針指向文件頭,若是文件不存在會報錯;'w'只寫模式打開文件,並將文件指針指向文件頭,若是文件存在則將其內容清空,不存在則建立;'a'以只追加可寫模式打開文件,並將文件指針指向文件尾部,若是文件不存在則建立。對應於open()方法打開文件須要有close()方法關閉文件。異步
f = open('/mnt/media/log.txt', 'r') f.read() f.close()
因爲讀寫文件時都有可能產生IOError,好比文件不存在的狀況,此時open()方法會拋出一個IOError的異常,那麼後面的f.close()就不會被調用。爲了保證不管是否出錯都能正確地關閉文件,咱們可使用try ... finally來實現。編程語言
try: f = open('/mnt/media/log.txt', 'r') f.read() finally: if f: f.close()
因爲try ... finally方式實現較爲繁瑣,Python引入了with語句會自動調用f.close()方法,使得代碼更簡潔。ide
with open('/mnt/media/log.txt', 'r') as f: f.read()
大文件讀取幾種方式工具
對文件的讀取操做是將文件中的數據加載到內存中,那麼對於大文件的讀取,若是一次把文件中所有的內容所有加載到內存中顯然會耗盡系統的內容。咱們看下Python中讀取文件經常使用的方法read()、readline()、readlines()對於大文件讀取的支持狀況:read(size)方法是從文件當前位置起讀取size個字節,若無參數size,則表示讀取至文件結束爲止,若是文件比較小,用read()一次讀取文件較爲方便,但若是不能肯定文件大小,反覆調用read(size)比較保險;readline()方法每次讀出一行內容,因此讀取時佔用內存小,比較適合大文件。readlines()方法讀取整個文件全部行,保存在一個列表list變量中,每行做爲一個元素,讀取大文件時比較佔內存。學習
說到大文件的讀取,有個linecache模塊,這裏要說明下的是這個模塊的優點是經過緩存文件內容的方式來加快下次讀取文件的速度,因此須要耗費更多的內存,那麼如下是我在Linux發行版LEDE+MT7688的環境下對readlines、linecache.getlines以及遍歷文件這三種方式在內存的使用狀況下的對比:開發工具
在學習過程當中有什麼不懂得能夠加個人 python學習交流扣扣qun,784-758-214 羣裏有不錯的學習視頻教程、開發工具與電子書籍。 與你分享python企業當下人才需求及怎麼從零基礎學習好python,和學習什麼內容 count = len(open(filepath, 'r').readlines()) _________________________________________________________ count = = len(linecache.getline(filepath) ) _________________________________________________________ count = 0 for count, line in enumerate(open(filepath,'r')): pass count += 1 ________________________________________________ count = len([ "" for line in open("filename","r")])
不打開文件:Mem: 37648K used, 88184K free, 116K shrd, 0K buff, 12540K cached readlines讀取文件:Mem: 69560K used, 56272K free, 124K shrd, 0K buff, 27004K cached linecache.getlines讀取文件:Mem: 70396K used, 55436K free, 116K shrd, 0K buff, 26996K cached 遍歷方式讀取文件:Mem: 53032K used, 72800K free, 116K shrd, 0K buff, 27668K cached
可是linecache.getlines在讀取文件的速度上是有絕對優點的,由於文件內容已經緩存在內存中了,下次讀取能夠直接從內存中獲取,可使用linecache.checkcache檢測文件在磁盤上是否發生了變化,若是變化了須要使用linecache.updatecache更新緩存。不過首次讀取文件須要打開文件,對於一個15M左右20000行的日誌文件三種方式差很少須要八、9秒的時間,但第二次讀取文件linecache.getlines方式是微秒級的。操作系統
readlines讀取文件:
time count 215794 type1 is 9.58759188652
time count 215794 type1 is 1.70862102509
time count 215794 type1 is 2.05462002754
time count 215794 type1 is 1.69754505157
time count 215813 type1 is 2.1633579731
time count 215813 type1 is 1.61879992485
遍歷方式讀取文件:
time count 215508 type2 is 8.8404238224
time count 215508 type3 is 2.22844409943
time count 215508 type2 is 2.19772100449
time count 215508 type3 is 2.57516384125
time count 215586 type2 is 2.12095785141
time count 215586 type3 is 2.55960321426
time count 215586 type2 is 2.1704659462
time count 215586 type3 is 2.11596107483
linecache.getlines讀取文件:
time count 214811 type4 is 8.19337201118
time count 214811 type4 is 6.50882720947e-05
time count 214811 type4 is 9.41753387451e-05
time count 214811 type4 is 6.69956207275e-05
time count 214811 type4 is 9.41753387451e-05
time count 214811 type4 is 6.89029693604e-05
以爲文章還能夠的話不妨收藏起來慢慢看,有任何意見或者見解歡迎你們評論!