os.path.join访问阻止重命名操作的文件

时间:2019-05-13 15:20:22

标签: python io path

我试图通过在解码失败时备份格式错误的文件来处理JSON解码,但是我遇到了一些奇怪的行为,这些行为我从os.path.join方法中没想到。

以下代码失败,但有一个例外:PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'file.txt' -> 'file.txt\\.bak'

file_path = "file.txt"

try:
    with open(file_path, 'r') as f:
        json.load(f)

except json.JSONDecodeError as e:
    os.rename(file_path, os.path.join(file_path, '.bak'))

如果我这样更改参数:os.rename(file_path, file_path + '.bak')该代码将按预期执行,而不会出现权限错误。看来os.path.join方法实际上是在访问文件,而不是严格的字符串操作。这是预期的行为吗?

2 个答案:

答案 0 :(得分:1)

os.path.join(file_path, '.bak'))实际上将为您提供file.txt\\.bak,就像您在错误代码中看到的一样,但是file_path + '.bak'为您提供了正确的文件名file.txt.bak

os.path.join在其参数之间附加分隔符,因此最终也会在您的情况下添加该分隔符

在MacOS中的示例,您可以看到它在每个参数之间添加了一个分隔符。 os.path.join对于附加目录名(带有目录路径的完整文件名)更为有用。

In [4]: import os                                                                                                                                                                 

In [5]: os.path.join('filename','.bak')                                                                                                                                           
Out[5]: 'filename/.bak'

In [6]: os.path.join('folder1', 'folder2')                                                                                                                                        
Out[6]: 'folder1/folder2'

发生错误是因为Windows操作系统试图在名为.bak的文件夹中制作文件file.txt,这是不可能的,因为file.txt是纯文件而不是目录,是正确的。

使用file_path+'.bak在所需的文件夹中正确创建file.path.bak,因此在该文件夹中看不到错误!

答案 1 :(得分:1)

错误消息是关键。像通常在Windows上那样,原因(因为它正在被另一个进程使用)是错误的,但是名称('file.txt'->'file.txt \ .bak')是正确的。

Join不是字符串连接,但是希望除最后一个路径之外的所有路径成员都代表文件夹。因此,您在这里尝试在名为.bak文件夹中制作文件file.txt。这是不可能的,因为file.txt是纯文件而不是目录。

另一方面,当您使用os.rename(file_path, file_path + '.bak')时,您正在将file.txt重命名为file.txt.bak,位于基础文件系统允许的同一文件夹中,因此没有错误。

因此,除了错误消息的开头之外,其他行为完全符合预期。


由于我不是Microsoft核心开发人员,因此以下是一个疯狂的猜测。系统给出的错误数量是有限的。重命名C函数收到2个字符串,并将其传递给系统调用以进行重命名。正如预期的那样,文件系统生成了一个错误,但是由于它既不是物理错误也不是文件系统已满错误,因此它只是选择了权限被拒绝的原因。这并不是真的错误,因为不允许在纯文件下创建文件夹。但是不幸的是,该错误的消息是,因为它正在被另一个进程使用,在此很愚蠢