Python 语言进阶 —— tempfile
介绍
tempfile
是 Python 标准库
中的一个用于创建临时文件和临时目录的模块。该模块支持所有的平台。该模块提供了如下的高阶接口:TemporaryFile
、
NamedTemporaryFile
、TemporaryDirectory
、SpooledTemporaryFile
。
因为这些高级接口实现了 __enter__
和 __exit__
两个特殊方法,所以它们可以和上下文管理器一同使用,用于在结束时清理这些临时文件。
同时,tempfile
模块也提供了手动清理的一些低级接口:mkstemp
和 mkdtemp
。
创建临时文件
在 tempfile
模块中可以使用 TemporaryFile
、NamedTemporaryFile
和 mkstemp
创建临时文件。
TemporaryFile
TemporaryFile
的定义如下:
def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
newline=None, suffix=None, prefix=None,
dir=None, errors=None):
TemporaryFile
返回的是一个类文件对象,支持文件的 I/O,用于临时数据的保存。默认模式为 w+b
,表示以二进制模式读写文件。也可以设置成 w+t
模式将文本数据写入到临时文件。TemporaryFile 函数中的 prefix
和 suffix
可以设置文件的前缀和后缀。TemporaryFile
生成的对象可以用作上下文管理器,当完成操作后,临时文件会从系统删除。
import tempfile
def main():
with tempfile.TemporaryFile(dir='./', prefix='test-', suffix='_txt') as tf:
print(tf)
print(tf.name)
tf.write(b'Hello World')
tf.seek(0)
print(tf.read())
if __name__ == '__main__':
main()
运行代码后,输出:
<tempfile._TemporaryFileWrapper object at 0x000002A1EA66CB50>
D:\Projects\Python\PythonDemos\test-32w35j6z_txt
b'Hello World'
mode
参数默认值为w+b
,写字符串时每次都需要转换成二进制写入。可以设置为w+
模式,这样就可以直接写入字符串类型。
NamedTemporaryFile
NamedTemporaryFile
的定义如下:
def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
newline=None, suffix=None, prefix=None,
dir=None, delete=True, errors=None):
NamedTemporaryFile
的用法和 TemporaryFile
完全相同,不同的是使用 NamedTemporaryFile
创建临时文件在文件系统上是可见的。可以从返回的类文件对象的 name
属性中检索该文件名。当参数 delete
为 True
时,表示一旦文件关闭就会被删除。
import os.path
import tempfile
def main():
with tempfile.NamedTemporaryFile(dir='./', prefix='test-', suffix='_txt', delete=False) as ntf:
ntf.write(b'Hello World')
ntf.seek(0)
print(ntf.read())
print(os.path.exists(ntf.name))
if __name__ == '__main__':
main()
运行代码后,输出;
b'Hello World'
True
SpooledTemporaryFile
SpooledTemporaryFile
的定义如下:
class SpooledTemporaryFile(_io.IOBase):
"""Temporary file wrapper, specialized to switch from BytesIO
or StringIO to a real file when it exceeds a certain size or
when a fileno is needed.
"""
def __init__(self, max_size=0, mode='w+b', buffering=-1,
encoding=None, newline=None,
suffix=None, prefix=None, dir=None, errors=None):
SpooledTemporaryFile
用法与 NamedTemporaryFile
和 TemporaryFile
基本相同。但是,SpooledTemporaryFile
会将数据缓存在内存中,直到超过 max_size
或调用文件的 fileno()
方法时,才会将数据写入到磁盘。
mktemp
Danger
mktemp
创建文件是不安全的。因为在调用 mktemp()
和随后的第一个进程尝试创建文件之间的时间内,不同的进程可能会创建一个具有此名称的文件。
解决方法是将这两个步骤结合起来,立即创建文件。自 2.3 版起已弃用: 改用 mkstemp()
。
mktemp
的定义如下:
def mktemp(suffix="", prefix=template, dir=None):
mktemp
函数中的参数含义如下:
suffix
:指定临时文件名的后缀信息。prefix
:指定临时文件名的前缀信息。dir
:指定临时文件默认保存的路径。
tmp = tempfile.mktemp(dir='./')
print(tmp)
with open(tmp, 'w+') as f: # mktemp 只生成路径,并没有生成文件,需要手动调用 open 打开文件
f.write('hello world')
f.seek(0)
print(f.read())
运行代码后,输出:
./tmpi6kodjcn
hello world
mkstemp
mkstemp
的定义如下:
def mkstemp(suffix=None, prefix=None, dir=None, text=False)
mktemp
是不安全的,但是 mkstemp
是安全的。
与 TemporaryFile()
不同,mkstemp()
的用户负责在完成后删除临时文件。mkstemp()
返回一个包含操作系统级句柄的元组到一个打开的文件(由
os.open()
返回)和该文件的绝对路径名,系统级句柄表示的是文件的安全级别。
temp = tempfile.mkstemp()
print(temp)
fd = temp[1]
with open(fd, 'w+') as f:
f.write('hello world')
f.seek(0)
print(f.read())
运行代码后,输出:
(3, 'C:\\Users\\harve\\AppData\\Local\\Temp\\tmpk01c8r2o')
hello world
创建临时目录
TemporaryDirectory
TemporaryFile
和 mkdtemp()
一样,都是以安全的方式创建对象。TemporaryFile
生成的对象可以用作上下文管理器,完成上下文或销毁临时目录对象后,将从文件系统中删除创建的临时目录。
通过 TemporaryFile
返回对象的 name
属性获取到临时目录的名称。 当返回的对象用作上下文管理器时,name
将分配给 with
语句中 as
子句的目标。可以通过调用 cleanup()
方法显示清理目录。
mkdtemp
以最安全的方式创建临时目录。 目录的创建中没有竞争条件。 该目录只能通过创建用户 ID 进行读取、写入和搜索。mkdtemp()
的用户负责删除临时目录及其内容。
其他方法
在 tempfile
模块中,还提供了一些其他方法:
gettempdir()
:返回用于临时文件的目录的名称。这定义了此模块中所有函数的dir
参数的默认值。gettempdirb()
:与gettempdir()
相同,但返回值以字节为单位。gettempprefix()
:返回用于创建临时文件的文件名前缀。 这不包含目录组件。gettempprefixb()
:与 gettempprefix() 相同,但返回值以字节为单位。tempdir()
:当设置为 None 以外的值时,此变量定义了此模块中定义的函数的dir
参数的默认值。