一、I/O操作概述 I/O概述: I/O在電腦中時指Input/Output,也就是Stream的輸入與輸出。我們通常說的輸入與輸出其實在操作系統中都是相對於記憶體而言的,InputStream(輸入流)是指數據從外部(網路、鍵盤、I/O設備)流進記憶體,OutputStream正好與之相反,數據從內 ...
一、I/O操作概述
I/O概述:
I/O在電腦中時指Input/Output,也就是Stream的輸入與輸出。我們通常說的輸入與輸出其實在操作系統中都是相對於記憶體而言的,InputStream(輸入流)是指數據從外部(網路、鍵盤、I/O設備)流進記憶體,OutputStream正好與之相反,數據從記憶體流出到外部。程式運行時,數據都是在哎記憶體中駐留,由CPU這個超級快的計算核心來執行,涉及到數據交換的地方就需要IO介面。IO介面的提供以及高級編程語言中的IO操作的實現:
操作系統十個通用的軟體程式,其通用目的如下: 硬體驅動、進程管理、記憶體管理、網路管理、安全管理、I/O管理 操作系統屏蔽了底層硬體,向上提供通用介面。因此,操作I/O的能力是由操作系統提供的,每一種編程語言都會把操作系統提供的低級C介面封裝起來供開發者使用,Python也不例外。二、文件讀寫實現原理和操作步驟
1.文件讀寫實現原理:
由於操作I/O的能力是由操作系統提供的,且操作系統不允許普通程式直接操作磁碟,所以讀寫文件時需要操作系統打開一個對象,這個對象通常被稱之為文件描述符--file descriptor,簡稱fd,這個就是我們在程式中要操作的文件對象。 通常高級編程語言會提供一個內置的函數,通過接收‘文件路徑’、‘文件打開模式’等參數來打開一個文件對象,並返回該文件對象的文件描述符。因此通過這個函數我們就可以獲取到要操作的文件對象,在Python中這個函數叫open(),在PHP中叫fopen()2.文件讀寫操作步驟:
不同編程語言讀寫文件的操作步驟大體都一樣,都分為以下幾步: 1)打開文件,獲取文件描述符; 2)操作文件描述符--讀/寫; 3)關閉文件。3.需要註意的是:
文件讀寫操作完成後,應該及時關閉。一方面,文件對象會占用操作系統的資源,另一方面,操作系統對同一時間能夠打開的文件描述符的數量是有限的,在linux操作系統上可以通過ulimit -n來查看這個現實數量。如果不能及時關閉文件,還可能造成數據丟失,因為將數據寫入文件時,操作系統不會立即把數據寫入磁碟,而是先把數據放到記憶體緩存區非同步寫入磁碟。當調用close方法時,操作系統才會保證把沒有寫入磁碟的數據全部寫入到磁碟,否則可能會丟失數據。三、Python3中文件打開模式
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)
打開文件的參數通常有:文件路徑名稱、mode參數(即打開模式)、編碼模式... 這裡需要搞清楚的就是mode參數,也就是我們使用什麼模式打開一個文件: Python3源碼中時這樣解釋的: Python3源碼文件其實對文件的打開模式進行了詳細的英文闡述,這裡非常建議大家自己打開builtins.py文件自行查看,我相信研究看懂的遠遠比看別人寫的文章描述的更加深刻。 這裡只是粘貼一部分打開模式的簡單描述部分: ========= =============================================================== Character Meaning --------- --------------------------------------------------------------- 'r' open for reading (default) 'w' open for writing, truncating the file first 'x' create a new file and open it for writing 'a' open for writing, appending to the end of the file if it exists 'b' binary mode 't' text mode (default) '+' open a disk file for updating (reading and writing) 'U' universal newline mode (deprecated) ========= =============================================================== 接下來我們隊幾個常見且重要的模式進行中文解析:打開模式 | 描述 |
r | 以只讀模式打開文件,並將文件指針指向文件開頭;如果文件不存在則報錯。 |
w | 以只寫模式打開文件,並將文件指針指向文件開頭;如果文件存在則將其情況並寫入,如果文件不存在則創建 |
a | 以只追加寫模式打開文件,並將文件指針指向文件末尾;如果文件不存在則創建。 |
r+ | 在r的基礎上增加可寫功能 |
w+ | 在w的基礎上增加可讀功能 |
a+ | 在a的模式上增加可讀功能 |
b | 讀寫二進位文件(預設是t,表示文本模式),需要與上面幾種模式搭配使用,如:ab,wb,ab |
x | 創建一個新文件再打開它寫入;如果文件已存在則報錯。 |
打開模式 | 詳細描述 |
r+ | 會覆蓋當前文件指針所在位置的字元,如原來文件內容是“Hello World”,以r+模式打開文件寫入“hi”則文件內容變成“hillo World” |
w+ | w+在打開文件時就會先將文件內清空,再進行寫入。 |
a+ | 該模式只能寫在文件末尾,也就是在文件末尾進行追加寫入。 |
四、Python文件操作實例
讀取文件open_test.py,該文件的字元編碼為utf-8 Python3實現: 輸出結果: 這裡需要註意一點就是,我們在讀寫文件時候,特別是在讀的時候大部分情況,如果文件路徑不正確或者文件不存在,也就是找不到文件,又或者是在進行文件操作時候出現I/O錯誤,就會報錯。此時如果要保證代碼的健壯性最好加上try...finally來實現錯誤捕捉以及及時關閉文件對象(優化代碼如下): 輸出結果: 上面關閉文件的代碼有時候很容易忘記,所以我們接下來使用Python with方法來完成自動關閉文件: 輸出結果: 可以看到在with語句中文件時沒有關閉的,只有出了with語句後文件會自動關閉 關於Python with上下文管理的用法可以查看文章瞭解: https://www.cnblogs.com/suguangti/p/11123515.html五、Python文件讀取相關方法
對文件的讀取操作需要將文件中的數據載入到記憶體中,而在上面所用到的read()方法會一次性的把文件中所有的內容全部載入到記憶體中。這顯然是不合理的,如果我們讀取的是一個大文件,有幾個G的文件時,必然會耗光機器的記憶體或者直接報錯,所以肯定有一些其他的讀取方法來解決:方法 | 描述 |
read() | 一次性讀取文件所有內容 |
read(size) | 每次最多讀取指定長度內容,在Python2中size指定是位元組長度,而在Python3中size指定為字元長度 |
readlines() | 一次性讀取文件所有內容,按行返回一個list |
readline() | 每次只讀取一行內容 |
方法 | 描述 |
seek() | 將文件指針移動到指定位元組位置 |
tell() |
實例一:
輸出結果:實例二:
輸出結果: readlines()方法跟read()方法一樣,都會消耗大量記憶體空間。實例三:
或者: 輸出結果:解決列印每一行換行符問題:
方法一: 方法二: 輸出結果:六、文件操作其他方法
方法 | 描述 |
flush() | 刷新緩衝區數據,將緩衝區中的數據立刻寫入文件 |
next() | 返迴文件下一行,這個方法也是file對象實例可以被當作迭代器使用的原因 |
truncate(size) | 截取文件中指定位元組數的內容,並覆蓋保存到文件中,如果不指定size參數,則文件將被清空;Python2中無返回值,Python3返回新文件的內容位元組數 |
write(str) | 將字元寫入文件,沒有返回值 |
writelines(sequence) | 向文件寫入一個字元串貨一個字元串列表,如果字元串列表中元素需要換行要自己加入換行符 |
fileno() | 返回一個整型的文件描述符,可以用於一些底層I/O操作上(如os模塊的read方法) |
issatty() | 判斷文件是否被連接到一個虛擬終端,是則返回True,否則返回False |