这是执行的屏幕截图:
如您所见,错误表明目录“JSONFiles/Apartment/Rent/dubizzleabudhabiproperty”不存在。
但是请看我的文件:
文件夹肯定在那里。
更新 2
代码
self.file = open("JSONFiles/"+ item["category"]+"/" + item["action"]+"/"+ item['source']+"/"+fileName + '.json', 'wb') # Create a new JSON file with the name = fileName parameter
line = json.dumps(dict(item)) # Change the item to a JSON format in one line
self.file.write(line) # Write the item to the file
更新
当我将文件名更改为较小的文件名时,它起作用了,所以问题是因为路径的长度。请问解决方法是什么?
原文由 Marco Dinatsoli 发布,翻译遵循 CC BY-SA 4.0 许可协议
常规 DOS 路径限制为
MAX_PATH
(260) 个字符,包括字符串的终止NUL
字符。您可以使用以\\?\
前缀开头的扩展长度路径来超过此限制。此路径必须是 Unicode 字符串,完全限定,并且仅使用反斜杠作为路径分隔符。根据 Microsoft 的 文件系统功能比较,最大扩展路径长度为 32760 个字符。单个文件或目录名称最多可包含 255 个字符(UDF 文件系统为 127 个)。扩展的 UNC 路径也支持\\?\UNC\server\share
。例如:
请参阅 MSDN 上的以下页面:
背景
Windows 调用 NT 运行时库函数
RtlDosPathNameToRelativeNtPathName_U_WithStatus
将 DOS 路径转换为本机 NT 路径。如果我们open
(即CreateFile
)上面的路径在后一个函数上设置了断点,我们可以看到它如何处理以\\?\
开头的路径字首。结果将
\\?\
替换为 NT DOS 设备前缀\??\
,并将字符串复制到本地UNICODE_STRING
:如果您使用
//?/
而不是\\?\
,那么路径仍然限于MAX_PATH
字符。如果太长,则RtlDosPathNameToRelativeNtPathName
返回状态码STATUS_NAME_TOO_LONG
(0xC0000106)。如果您使用
\\?\
作为前缀,但在路径的其余部分使用斜杠,Windows 不会 为您将斜杠转换为反斜杠:正斜杠是 NT 名称空间中的有效对象名称字符。它由 Microsoft 文件系统保留,但您可以在其他命名的内核对象中使用正斜杠,这些对象存储在
\BaseNamedObjects
或\Sessions\[session number]\BaseNamedObjects
中。此外,我认为 I/O 管理器不会强制执行设备和文件名中保留字符的策略。这取决于设备。也许有人有一个 Windows 设备实现了一个允许在名称中使用正斜杠的名称空间。至少您可以创建包含正斜杠的 DOS 设备名称。例如:您可能想知道
\??
是什么意思。这曾经是对象命名空间中 DOS 设备链接的实际目录,但从 NT 5(或带有终端服务的 NT 4)开始,这变成了一个虚拟前缀。对象管理器通过首先检查目录\Sessions\0\DosDevices\[LOGON_SESSION_ID]
中的登录会话的 DOS 设备链接来处理此前缀,然后检查\Global??
目录中的系统范围 DOS 设备链接。请注意,前者是登录会话,而不是 Windows 会话。登录会话目录都在
DosDevices
Windows会话0(即Vista+中的服务会话)目录下。因此,如果您有用于非提升登录的映射驱动器,您会发现它在提升命令提示符中不可用,因为提升令牌实际上用于不同的登录会话。DOS 设备链接的示例是
\Global??\C:
=>\Device\HarddiskVolume2
。在这种情况下,DOSC:
驱动器实际上是指向HarddiskVolume2
设备的符号链接。下面是系统如何处理解析路径以打开文件的简要概述。 Given we’re calling WinAPI
CreateFile
, it stores the translated NTUNICODE_STRING
in anOBJECT_ATTRIBUTES
structure and calls the system functionNtCreateFile
.NtCreateFile
调用 I/O 管理器函数IoCreateFile
,它又调用未记录的对象管理器 APIObOpenObjectByName
这完成了解析路径的工作。对象管理器以\??\C:\Temp\test.txt
开头。然后将其替换为\Global??\C:Temp\test.txt
。接下来它解析到C:
符号链接并且必须重新开始(重新解析)最终路径\Device\HarddiskVolume2\Temp\test.txt
。一旦对象管理器到达
HarddiskVolume2
设备对象,解析就会交给 I/O 管理器,后者实现Device
对象类型。 TheParseProcedure
of an I/ODevice
creates theFile
object and an I/O Request Packet (IRP) with the major function codeIRP_MJ_CREATE
(打开/创建操作)由设备堆栈处理。这通过IoCallDriver
发送到设备驱动程序。如果设备实现了重解析点(例如连接挂载点、符号链接等)并且路径包含重解析点,则解析后的路径必须重新提交给对象管理器以便从头开始解析。设备驱动程序将使用进程令牌(或模拟线程)的
SeChangeNotifyPrivilege
(几乎始终存在并启用)在遍历目录时绕过访问检查。但是,最终必须通过安全描述符来允许访问设备和目标文件,该安全描述符通过SeAccessCheck
验证。除了像 FAT32 这样的简单文件系统不支持文件安全。