1. tempfile臨時檔案系統物件
要想安全的創建名字唯一的臨時檔案,以防止被試圖破壞應用或竊取資料的人猜出,這很有難度,tempfile模塊提供了多個函式來安全的創建臨時檔案系統資源,TemporaryFile()打開并回傳一個未命名的檔案,NamedTemporaryFile()打開并回傳一個命名檔案,SpooledTemporaryFile在將內容寫入磁盤之前先將其保存在記憶體中,TemporaryDirectory是一個背景關系管理器,背景關系關閉時會洗掉這個目錄,
1.1 臨時檔案
如果應用需要臨時檔案來存盤資料,而不需要與其他程式共享這些檔案,則應當使用TemporaryFile()函式創建檔案,這個函式會創建一個檔案,而且如果平臺支持,它會立即斷開這個新檔案的鏈接,這樣一來,其他程式就不可能找到或打開這個檔案,因為檔案系統表中根本沒有這個檔案的參考,對于TemporaryFile()創建的檔案,無論通過呼叫close()還是結合使用背景關系管理器API和with陳述句,關閉檔案時都會自動洗掉這個檔案,
import os import tempfile print('Building a filename with PID:') filename = '/guess_my_name.{}.txt'.format(os.getpid()) with open(filename, 'w+b') as temp: print('temp:') print(' {!r}'.format(temp)) print('temp.name:') print(' {!r}'.format(temp.name)) # Clean up the temporary file yourself. os.remove(filename) print() print('TemporaryFile:') with tempfile.TemporaryFile() as temp: print('temp:') print(' {!r}'.format(temp)) print('temp.name:') print(' {!r}'.format(temp.name))
這個例子展示了采用不同方法創建臨時檔案的差別,一種做法是使用一個通用模式來構造臨時檔案的檔案名,另一種做法是使用TemporaryFile()函式,TemporaryFile()回傳的檔案沒有檔案名,

默認的,檔案句柄是使用模式'w+b'創建的,以便它在所有平臺上都表現一致,并允許呼叫者讀寫這個檔案,
import os import tempfile with tempfile.TemporaryFile() as temp: temp.write(b'Some data') temp.seek(0) print(temp.read())
寫檔案之后,必需使用seek()"回轉"檔案句柄以便從檔案讀回資料,

要以文本模式打開檔案,創建檔案時要設定mode為'w+t',
import tempfile with tempfile.TemporaryFile(mode='w+t') as f: f.writelines(['first\n', 'second\n']) f.seek(0) for line in f: print(line.rstrip())
這個檔案句柄將把資料處理為文本,

1.2 命名檔案
有些情況下,可能非常需要一個命名的臨時檔案,對于跨多個行程甚至主機的應用來說,為檔案命名是在應用不同部分之間傳遞檔案的最簡單的方法,NamedTemporaryFile()函式會創建一個檔案,但不會斷開它的鏈接,所以會保留它的檔案名(用name屬性訪問),
import os import pathlib import tempfile with tempfile.NamedTemporaryFile() as temp: print('temp:') print(' {!r}'.format(temp)) print('temp.name:') print(' {!r}'.format(temp.name)) f = pathlib.Path(temp.name) print('Exists after close:', f.exists())
句柄關閉后檔案將被洗掉,

1.3 假脫機檔案
如果臨時檔案中包含的資料相對較少,則使用SpooledTemporaryFile可能更高效,因為它使用一個io.BytesIO或io.stringIO緩沖區在記憶體中保存內容,直到資料達到一個閾值時,資料將“滾動”并寫入磁盤,然后用常規的TemporaryFile()替換這個緩沖區,
import tempfile with tempfile.SpooledTemporaryFile(max_size=100, mode='w+t', encoding='utf-8') as temp: print('temp: {!r}'.format(temp)) for i in range(3): temp.write('This line is repeated over and over.\n') print(temp._rolled, temp._file)
這個例子使用SpooledTemporaryFile的私有屬性來確定何時滾動到磁盤,除非要調整緩沖區大小,否則很少需要檢查這個狀態,

要顯示的將緩沖區寫至磁盤,可以呼叫rollover()或fileno()方法,
import tempfile with tempfile.SpooledTemporaryFile(max_size=1000, mode='w+t', encoding='utf-8') as temp: print('temp: {!r}'.format(temp)) for i in range(3): temp.write('This line is repeated over and over.\n') print(temp._rolled, temp._file) print('rolling over') temp.rollover() print(temp._rolled, temp._file)
在這個例子中,由于緩沖區非常大,遠遠大于實際的資料量,所以除非呼叫rollover(),否則不會在磁盤上創建任何檔案,

1.4 臨時目錄
需要多個臨時檔案時,可能更方便的做法是用TemporaryDirectory創建一個臨時目錄,并打開該目錄中的所有檔案,
import pathlib import tempfile with tempfile.TemporaryDirectory() as directory_name: the_dir = pathlib.Path(directory_name) print(the_dir) a_file = the_dir / 'a_file.txt' a_file.write_text('This file is deleted.') print('Directory exists after?', the_dir.exists()) print('Contents after:', list(the_dir.glob('*')))
背景關系管理器會生成目錄名,可以在背景關系塊中用來建立其他檔案名,

1.5 臨時檔案位置
如果沒有使用dir引數指定明確的目標位置,則臨時檔案使用的路徑會根據當前平臺和設定而變化,tempfile模塊包括兩個函式來查詢運行時使用的設定,
import tempfile print('gettempdir():', tempfile.gettempdir()) print('gettempprefix():', tempfile.gettempprefix())
gettempdir()回傳包含所有臨時檔案的默認目錄,gettempprefix()回傳新檔案和目錄名和字串前綴,


gettempdir()回傳的值根據一個簡單演算法來設定,它會查找一個位置串列,尋找第一個允許當前行程創建檔案的位置,
import tempfile tempfile.tempdir = '/I/changed/this/path' print('gettempdir():', tempfile.gettempdir())
如果程式需要對所有臨時檔案使用一個全域位置,但不使用以上任何環境變數,則應當直接設定tempfile.tempdir,為該變數賦一個值,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/176255.html
標籤:Python
