OS.Path.join访问可以防止重命名操作的文件



我试图在解码失败时备份错误的文件来处理JSON解码,但是我经历了一些奇怪的行为,我从os.path.join方法中没有期望。p>以下代码失败,例外: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方法实际上访问了文件,而不是严格的字符串操作。这是预期的行为吗?

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 OS试图在名为file.txt的文件夹中制作文件.bak,因此发生了错误,这是不可能的,因为File.txt是一个普通文件,而不是正确的目录,这是正确的。

使用file_path+'.bak在您想要的文件夹中正确创建file.path.bak,因此您在那里看不到错误!

错误消息是密钥。通常在Windows上(((由于另一个进程使用(是错误的,但是名称('file.txt' ->'file.txt .bak'(是正确的。

加入不是字符串串联,而是期望除最后一个表示文件夹外的所有路径成员。因此,在这里,您正在尝试在文件夹中制作一个文件.bak>命名file.txt。不可能,因为file.txt是一个普通文件,而不是目录。

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

因此,行为正是预期的,除了错误消息的开始。


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

相关内容

  • 没有找到相关文章

最新更新