python死磕四之文件與IO
利用python進行文件操作在我們平常項目中也經常用到,下面是我日常工作中忽略或者沒有遇到過的集中情況。
一、你想將 print()
函數的輸出重定向到一個文件中去。
在 print()
函數中指定 file
關鍵字參數,像下面這樣:
with open(‘d:/work/test.txt‘, ‘wt‘) as f: # 這裏的t是windows文件text的特有形式,會識別出換行符 print(‘Hello World!‘, file=f)
註意:關於輸出重定向到文件中就這些了。但是有一點要註意的就是文件必須是以文本模式打開。 如果文件是二進制模式的話,打印就會出錯。
二、在讀取二進制數據的時候,字節字符串和文本字符串的語義差異。
註意:在讀取二進制文件中,索引和叠代動作返回的是字節的值而不是字節字符串。
>>> # Text string >>> t = ‘Hello World‘ >>> t[0] ‘H‘ >>> for c in t: ... print(c) ... H e l l o ... >>> # Byte string >>> b = b‘Hello World‘ >>> b[0]72 >>> for c in b: ... print(c) ... 72 101 108 108 111 ... >>>
如果你想從二進制模式的文件中讀取或寫入文本數據,必須確保要進行解碼和編碼操作。
with open(‘somefile.bin‘, ‘rb‘) as f: data = f.read(16) text = data.decode(‘utf-8‘) with open(‘somefile.bin‘, ‘wb‘) as f: text = ‘Hello World‘f.write(text.encode(‘utf-8‘))
三、你想像一個文件中寫入數據,但是前提必須是這個文件在文件系統上不存在。 也就是不允許覆蓋已存在的文件內容。
之前思路:用os模塊判斷這個文件名是否存在,再做讀寫操作。
遺漏點:可以在 open()
函數中使用 x
模式來代替 w
模式的方法來解決這個問題。
>>> with open(‘somefile‘, ‘wt‘) as f: ... f.write(‘Hello\n‘) ... >>> with open(‘somefile‘, ‘xt‘) as f: ... f.write(‘Hello\n‘) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> FileExistsEr
四、你想使用操作類文件對象的程序來操作文本或二進制字符串。
import io s = io.StringIO() # 實例化一個對象存在內存中 s.write(‘hello world\n‘) # 給對象寫操作 print(‘this is a test‘,file=s) res = s.getvalue() print(res)
io.StringIO
只能用於文本。如果你要操作二進制數據,要使用 io.BytesIO
類來代替。比如:
>>> s = io.BytesIO() >>> s.write(b‘binary data‘) >>> s.getvalue()
當你想模擬一個普通的文件的時候 StringIO
和 BytesIO
類是很有用的。 比如,在單元測試中,你可以使用 StringIO
來創建一個包含測試數據的類文件對象, 這個對象可以被傳給某個參數為普通文件對象的函數。
五、你想讀寫一個gzip或bz2格式的壓縮文件。
import gzip with gzip.open(‘somefile.gz‘, ‘rt‘) as f: text = f.read() # bz2 compression import bz2 with bz2.open(‘somefile.bz2‘, ‘rt‘) as f: text = f.read()
# gzip compression import gzip with gzip.open(‘somefile.gz‘, ‘wt‘) as f: f.write(text) # bz2 compression import bz2 with bz2.open(‘somefile.bz2‘, ‘wt‘) as f: f.write(text)
六、總結os模塊常用方法
1.os.path.dirname(path) # 獲得目錄名 2.os.path.join(path,filename) #可以拼接目錄名 3.os.path.splitext(path) # 得到文件路徑和格式名 4.os.path.exists(‘/tmp/spam‘) # 判斷文件是否存在 5.os.path.isfile(path) # 判斷是否是文件 6.os.path.isdir(path) # 判斷是否是目錄 7.os.path.getsize(path) # 獲得文件大小 8.os.path.getmtime(path) # 獲得文件修改時間 9.os.listdir(path) # 獲得目錄下所有文件
使用例子:使用 os.listdir()
函數來獲取某個目錄中的文件列表:
import os.path # Get all regular files names = [name for name in os.listdir(‘somedir‘) if os.path.isfile(os.path.join(‘somedir‘, name))] # Get all dirs dirnames = [name for name in os.listdir(‘somedir‘) if os.path.isdir(os.path.join(‘somedir‘, name))]
七、你需要在程序執行時創建一個臨時文件或目錄,並希望使用完之後可以自動銷毀掉。
tempfile
模塊中有很多的函數可以完成這任務。 為了創建一個匿名的臨時文件,可以使用 tempfile.TemporaryFile
:
from tempfile import TemporaryFile with TemporaryFile(‘w+t‘) as f: # Read/write to the file f.write(‘Hello World\n‘) f.write(‘Testing\n‘) # Seek back to beginning and read the data f.seek(0) data = f.read()
TemporaryFile()
的第一個參數是文件模式,通常來講文本模式使用 w+t
,二進制模式使用 w+b
。 這個模式同時支持讀和寫操作,在這裏是很有用的,因為當你關閉文件去改變模式的時候,文件實際上已經不存在了。 TemporaryFile()
另外還支持跟內置的 open()
函數一樣的參數。
with TemporaryFile(‘w+t‘, encoding=‘utf-8‘, errors=‘ignore‘) as f:
python死磕四之文件與IO