Chr*_* B. 11 python windows temporary-files
我有一个Python程序需要创建一个命名的临时文件,该程序将在程序过程中打开和关闭几次,并且应该在程序退出时删除.不幸的是,tempfile似乎没有任何选项可行:
TemporaryFile 没有可见的名字NamedTemporaryFile创建一个类文件对象.我只需要一个文件名.我已经尝试关闭它返回的对象(设置后delete = False),但是当我稍后尝试打开文件时出现流错误.SpooledTemporaryFile 没有可见的名字mkstemp返回打开的文件对象和名称; 它不保证程序退出时删除文件mktemp 返回文件名,但不保证程序退出时删除文件我尝试在上下文管理器中使用mktemp1,如下所示:
def get_temp_file(suffix):
class TempFile(object):
def __init__(self):
self.name = tempfile.mktemp(suffix = '.test')
def __enter__(self):
return self
def __exit__(self, ex_type, ex_value, ex_tb):
if os.path.exists(self.name):
try:
os.remove(self.name)
except:
print sys.exc_info()
return TempFile()
Run Code Online (Sandbox Code Playgroud)
......但这给了我一个WindowsError(32, 'The process cannot access the file because it is being used by another process').文件名由我的程序生成的进程使用,即使我确保在退出之前进程完成,但它似乎有一个不受我控制的竞争条件.
处理这个问题的最佳方法是什么?
1我不需要担心这里的安全问题; 这是测试模块的一部分,所以最邪恶的人可能会导致我们的单元测试虚假失败.惊恐的事件!
小智 5
我今天需要类似的东西,最后写了我自己的。我正在使用 atexit.register() 注册一个函数回调,该回调在程序退出时删除文件。
请注意,这方面的编码标准与典型的 Python 编码标准(驼峰式而不是 using_underscores)略有不同。当然可以随意调整。
def temporaryFilename(prefix=None, suffix='tmp', dir=None, text=False, removeOnExit=True):
"""Returns a temporary filename that, like mkstemp(3), will be secure in
its creation. The file will be closed immediately after it's created, so
you are expected to open it afterwards to do what you wish. The file
will be removed on exit unless you pass removeOnExit=False. (You'd think
that amongst the myriad of methods in the tempfile module, there'd be
something like this, right? Nope.)"""
if prefix is None:
prefix = "%s_%d_" % (os.path.basename(sys.argv[0]), os.getpid())
(fileHandle, path) = tempfile.mkstemp(prefix=prefix, suffix=suffix, dir=dir, text=text)
os.close(fileHandle)
def removeFile(path):
os.remove(path)
logging.debug('temporaryFilename: rm -f %s' % path)
if removeOnExit:
atexit.register(removeFile, path)
return path
Run Code Online (Sandbox Code Playgroud)
超基础测试代码:
path = temporaryFilename(suffix='.log')
print path
writeFileObject = open(path, 'w')
print >> writeFileObject, 'yay!'
writeFileObject.close()
readFileObject = open(path, 'r')
print readFileObject.readlines()
readFileObject.close()
Run Code Online (Sandbox Code Playgroud)
如果您不关心安全性,这有什么问题呢?
tmpfile_name = tempfile.mktemp()
# do stuff
os.unlink(tmpfile_name)
Run Code Online (Sandbox Code Playgroud)
您可能试图对此进行过度设计。如果您想确保在程序退出时始终删除该文件,您可以将main()执行包装在try/finally. 把事情简单化!
if __name__ == '__main__':
try:
tmpfile_name = tempfile.mktemp()
main()
except Whatever:
# handle uncaught exception from main()
finally:
# remove temp file before exiting
os.unlink(tmpfile_name)
Run Code Online (Sandbox Code Playgroud)