例如,在某項目中,我們從傳感器採集數據,每收集到1G數據後,做數據分析,最終只保存分析結果。這樣很大的臨時文件如果常駐內存,將消耗大量內存資源。
要求:使用臨時文件存儲這些臨時數據(外部存儲)。臨時文件不用命名,且關閉後會自動被刪除。
解決方案:
使用標準庫中的TemporaryFile
(臨時文件)以及NamedTemporaryFile
(命名臨時文件)。
- 對於
TemporaryFile()
:
TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None)
創建並返回一個臨時文件,該文件在文件系統中無法訪問。mode默認是二進制可讀可寫。
- 對於
NamedTemporaryFile()
:
NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True)
創建並返回一個命名的臨時文件,該文件在文件系統中可訪問,這是Python庫對臨時文件進行操作的。delete=True
表示文件在關閉時刪除。
- 對於
os.open()
方法:
os.open(path, flags, mode=511, *, dir_fd=None)
爲低級別IO打開一個文件,返回一個文件描述符(整數)。當flags
爲O_TMPFILE
時會創建一個臨時文件,關閉時刪除,這是操作系統對臨時文件進行操作。且指定路徑爲目錄(不是文件),即在該目錄下創建臨時文件。
- 方案示例:
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 18G 5.8G 13G 33% / #當前已使用5.8G
devtmpfs 900M 0 900M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.5M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/sda1 197M 148M 50M 75% /boot
tmpfs 182M 0 182M 0% /run/user/0
>>> from tempfile import TemporaryFile, NamedTemporaryFile
>>> tf = TemporaryFile()
>>> tf.write(b'*' * 1024 * 1024 * 1024) #寫入1G到臨時文件中
1073741824
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 18G 6.8G 12G 38% / #已使用增加1G
devtmpfs 900M 0 900M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.5M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/sda1 197M 148M 50M 75% /boot
tmpfs 182M 0 182M 0% /run/user/0
>>> tf.close() #關閉臨時文件
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 18G 5.8G 13G 33% / #已使用恢復
devtmpfs 900M 0 900M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.5M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/sda1 197M 148M 50M 75% /boot
tmpfs 182M 0 182M 0% /run/user/0
>>> ntf = NamedTemporaryFile()
>>> ntf.name
'/tmp/tmpvkj005cs' #該臨時文件名
# ll '/tmp/tmpvkj005cs'
-rw------- 1 root root 0 Sep 12 10:17 /tmp/tmpvkj005cs
NamedTemporaryFile()
創建的臨時文件名是通過suffix=None, prefix=None, dir=None
這幾個參數來決定的。
>>> import tempfile
>>> tempfile.gettemp
tempfile.gettempdir( tempfile.gettempdirb( tempfile.gettempprefix( tempfile.gettempprefixb(
>>> tempfile.gettempdir() #默認目錄
'/tmp'
>>> tempfile.gettempprefix() #默認前綴
'tmp'
這些默認參數都是可修改的。
>>> ntf.close()
# ll '/tmp/tmpvkj005cs'
ls: cannot access /tmp/tmpvkj005cs: No such file or directory
臨時文件關閉後會自動刪除,這是因爲delete
參數默認爲True。
通常情況下使用TemporaryFile
創建臨時文件即可,但是在多進程都想訪問同一臨時文件時,使用NamedTemporaryFile
創建命名臨時文件更爲合適。