gpt4 book ai didi

python - 在 os.rename() 之后更新文件描述符

转载 作者:太空宇宙 更新时间:2023-11-04 09:17:49 26 4
gpt4 key购买 nike

在按以下方式调用 os.rename() 后,处理 Bad file descriptor 错误的最佳方法是什么?

f = open('foo.txt', 'rw')
os.rename(f.name, f.name + ".bak")

在文件系统中不再有 foo.txt 而是 foo.txt.bak

然而..

f.name

给出 foo.txt 而不是 foo.txt.bak

但是..

f.write("test")

给出错误的文件描述符

有没有更新文件描述符的好方法?

即使文件已重命名,我是否仍应调用 f.close()

最佳答案

您可以编写一个函数来重命名打开的文件。基本上,您关闭、重命名和重新打开文件,同时保留文件位置和模式等属性。重新打开需要对模式进行一些调整——如果文件的模式是“w”,用相同的模式重新打开它会丢失其中的所有内容,所以在这种情况下,我们在重新打开时使用“r+”模式。 (这并不完美,因为它允许对文件进行读取访问,这在以前是没有的,但这是我们能做的最好的了。)你当然会得到一个全新的 file 对象, 这是函数的返回值。

import os

def rename_open_file(fileobj, newname):
name = fileobj.name
mode = fileobj.mode.lower()
posn = fileobj.tell()
fileobj.close()
os.rename(name, newname)
newmode = mode
if "w" in mode: # can't reopen with "w" mode since
newmode = "r+" # it would empty the file; use "r+"
if "b" in mode:
newmode += "b"
fileobj = open(name, newmode)
fileobj.seek(posn)
return fileobj

f = rename_open_file(f, f.name + ".bak")

如果您有多个 file 对象引用打开的文件,这当然无济于事;所有其他引用可能会中断。

警告:文件的 name 属性不一定是完整路径,因此如果您使用相对路径打开文件并在打开文件后更改了目录,则不会工作。如果这是一个问题,您可以编写自己的 open() 在打开时找出文件的完整路径名(使用 os.path.abspath())。

此外,打开文件时给出的缓冲区大小不会被保留,因为它不会记录在文件对象的任何位置。编写您自己的 open() 也可以解决这个问题。最简单的方法是子类化 file

from os.path import abspath
class open(file):
def __init__(self, filename, mode="r", buffering=-1):
file.__init__(self, abspath(filename), mode, buffering)
self.buffering = buffering

然后您可以将维护缓冲添加到您的函数中:

import os

def rename_open_file(fileobj, newname):
name = fileobj.name
mode = fileobj.mode.lower()
posn = fileobj.tell()
buff = fileobj.buffering
fileobj.close()
os.rename(name, newname)
newmode = mode
if "w" in mode: # can't reopen with "w" mode since
newmode = "r+" # it would empty the file; use "r+"
if "b" in mode:
newmode += "b"
fileobj = open(name, newmode, buff)
fileobj.seek(posn)
return fileobj

您还可以为文件对象编写一个包装器类,而不是子类化file,并让它通过所有file对包装对象的方法调用。然后 rename() 可以是包装器的一个方法,并执行上述所有操作。由于调用代码将保留对包装器的引用,因此它不需要知道底层 file 对象是否不同。我将把它留作练习。 :-)

关于python - 在 os.rename() 之后更新文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6697972/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com