27

我正在尝试使用“tempfile”模块来操作和创建文本文件。文件准备好后,我想将其保存到磁盘。我认为这就像使用'shutil.copy'一样简单。但是,我得到一个“权限被拒绝”的 IOError:

>>> import tempfile, shutil
>>> f = tempfile.TemporaryFile(mode ='w+t')
>>> f.write('foo')
>>> shutil.copy(f.name, 'bar.txt')

Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    shutil.copy(f.name, 'bar.txt')
  File "C:\Python25\lib\shutil.py", line 80, in copy
    copyfile(src, dst)
  File "C:\Python25\lib\shutil.py", line 46, in copyfile
    fsrc = open(src, 'rb')
IOError: [Errno 13] Permission denied: 'c:\\docume~1\\me\\locals~1\\temp\\tmpvqq3go'
>>> 

这不是在使用“tempfile”库时打算的吗?有一个更好的方法吗?(也许我忽略了一些非常琐碎的事情)

4

4 回答 4

43

hop 是对的,并且 dF。错误发生的原因不正确。

由于您尚未调用f.close(),因此该文件不会被删除。

文档NamedTemporaryFile说:

在命名的临时文件仍处于打开状态时,是否可以使用该名称再次打开文件,因平台而异(在 Unix 上可以这样使用;在 Windows NT 或更高版本上不能)。

对于TemporaryFile

在 Unix 下,文件的目录条目在文件创建后立即被删除。其他平台不支持;您的代码不应依赖于使用此函数创建的临时文件,该文件在文件系统中具有或不具有可见名称。

因此,要保留一个临时文件(在 Windows 上),您可以执行以下操作:

import tempfile, shutil
f = tempfile.NamedTemporaryFile(mode='w+t', delete=False)
f.write('foo')
file_name = f.name
f.close()
shutil.copy(file_name, 'bar.txt')
os.remove(file_name)

Hans Sjunnesson 提供的解决方案也是关闭的,因为copyfileobj仅从类文件对象复制到类文件对象,而不是文件名:

shutil.copyfileobj(fsrc, fdst[, 长度])

将类文件对象 fsrc 的内容复制到类文件对象 fdst。整数长度(如果给定)是缓冲区大小。特别是,负长度值意味着复制数据而不以块的形式循环源数据;默认情况下,数据以块的形式读取,以避免不受控制的内存消耗。注意,如果 fsrc 对象的当前文件位置不为 0,则只会复制从当前文件位置到文件末尾的内容。

于 2012-02-06T04:19:42.517 回答
21

您创建的文件TemporaryFileNamedTemporaryFile在关闭时自动删除,这就是您收到错误的原因。如果您不想要这个,您可以mkstemp改用(请参阅tempfile的文档)。

>>> import tempfile, shutil, os
>>> fd, path = tempfile.mkstemp()
>>> os.write(fd, 'foo')
>>> os.close(fd)
>>> shutil.copy(path, 'bar.txt')
>>> os.remove(path)
于 2008-09-18T16:45:37.793 回答
13

从 python 2.6 开始,您还可以使用设置为 FalseNamedTemporaryFile的选项。delete=这样,即使您关闭临时文件,也可以访问它。

请注意,在 Windows(NT 和更高版本)上,当文件仍处于打开状态时,您无法再次访问该文件。您必须先关闭它,然后才能复制它。这在 Unix 系统上是不正确的。

于 2008-09-20T22:15:33.667 回答
6

在您的示例中,您始终可以使用shutil.copyfileobj

new_file = open('bar.txt', 'rw')
shutil.copyfileobj(f, new_file)
于 2008-09-18T16:33:46.620 回答