日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python读取路径太长_路径名太长,无法打开?

發(fā)布時(shí)間:2025/3/20 python 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python读取路径太长_路径名太长,无法打开? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

常規(guī)DOS路徑限制為MAX_PATH(260)個(gè)字符,包括字符串的終止字符NUL。通過使用以\\?\前綴開頭的擴(kuò)展長度路徑,可以超過此限制。此路徑必須是完全限定的Unicode字符串,并且只能使用反斜杠作為路徑分隔符。根據(jù)Microsoft的file system functionality comparison,最大擴(kuò)展路徑長度為32760個(gè)字符。單個(gè)文件或目錄名最多可以包含255個(gè)字符(UDF文件系統(tǒng)為127個(gè)字符)。擴(kuò)展的UNC路徑也支持為\\?\UNC\server\share。

例如:import os

def winapi_path(dos_path, encoding=None):

if (not isinstance(dos_path, unicode) and

encoding is not None):

dos_path = dos_path.decode(encoding)

path = os.path.abspath(dos_path)

if path.startswith(u"\\\\"):

return u"\\\\?\\UNC\\" + path[2:]

return u"\\\\?\\" + path

path = winapi_path(os.path.join(u"JSONFiles",

item["category"],

item["action"],

item["source"],

fileName + ".json"))>>> path = winapi_path("C:\\Temp\\test.txt")

>>> print path

\\?\C:\Temp\test.txt

請參閱MSDN上的以下頁面:

背景

Windows調(diào)用NT運(yùn)行庫函數(shù)RtlDosPathNameToRelativeNtPathName_U_WithStatus將DOS路徑轉(zhuǎn)換為本機(jī)NT路徑。如果上面的路徑在后面的函數(shù)上設(shè)置了斷點(diǎn),我們可以看到它如何處理以前綴\\?\開頭的路徑。Breakpoint 0 hit

ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus:

00007ff9`d1fb5880 4883ec58 sub rsp,58h

0:000> du @rcx

000000b4`52fc0f60 "\\?\C:\Temp\test.txt"

0:000> r rdx

rdx=000000b450f9ec18

0:000> pt

ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus+0x66:

00007ff9`d1fb58e6 c3 ret

結(jié)果將\\?\替換為NT DOS設(shè)備前綴\??\,并將字符串復(fù)制到本機(jī)^{}:0:000> dS b450f9ec18

000000b4`536b7de0 "\??\C:\Temp\test.txt"

如果使用//?/而不是\\?\,則路徑仍限制為MAX_PATH個(gè)字符。如果太長,則RtlDosPathNameToRelativeNtPathName返回狀態(tài)代碼STATUS_NAME_TOO_LONG(0xc000106)。

如果使用\\?\作為前綴,但在路徑的其余部分使用斜杠,則Windows不會(huì)為您將斜杠轉(zhuǎn)換為反斜杠:Breakpoint 0 hit

ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus:

00007ff9`d1fb5880 4883ec58 sub rsp,58h

0:000> du @rcx

0000005b`c2ffbf30 "\\?\C:/Temp/test.txt"

0:000> r rdx

rdx=0000005bc0b3f068

0:000> pt

ntdll!RtlDosPathNameToRelativeNtPathName_U_WithStatus+0x66:

00007ff9`d1fb58e6 c3 ret

0:000> dS 5bc0b3f068

0000005b`c3066d30 "\??\C:/Temp/test.txt"

正斜杠是NT命名空間中的有效對象名字符。它由Microsoft文件系統(tǒng)保留,但您可以在其他命名的內(nèi)核對象中使用正斜杠,這些對象存儲(chǔ)在\BaseNamedObjects或\Sessions\[session number]\BaseNamedObjects中。另外,我不認(rèn)為I/O管理器對設(shè)備和文件名中的保留字符強(qiáng)制執(zhí)行策略。這取決于設(shè)備。也許有人有一個(gè)Windows設(shè)備,它實(shí)現(xiàn)了一個(gè)名稱空間,允許在名稱中使用正斜杠。至少可以創(chuàng)建包含正斜杠的DOS設(shè)備名。例如:>>> kernel32 = ctypes.WinDLL('kernel32')

>>> kernel32.DefineDosDeviceW(0, u'My/Device', u'C:\\Temp')

>>> os.path.exists(u'\\\\?\\My/Device\\test.txt')

True

你可能想知道\??意味著什么。這曾經(jīng)是對象名稱空間中DOS設(shè)備鏈接的實(shí)際目錄,但從NT 5(或NT 4 w/Terminal Services)開始,這就變成了一個(gè)虛擬前綴。對象管理器通過首先檢查目錄\Sessions\0\DosDevices\[LOGON_SESSION_ID]中登錄會(huì)話的DOS設(shè)備鏈接,然后檢查目錄\Global??中的系統(tǒng)范圍的DOS設(shè)備鏈接來處理此前綴。

請注意,前者是登錄會(huì)話,而不是Windows會(huì)話。登錄會(huì)話目錄都在Windows會(huì)話0的DosDevices目錄下(即Vista+中的服務(wù)會(huì)話)。因此,如果您有用于非提升登錄的映射驅(qū)動(dòng)器,您將發(fā)現(xiàn)它在提升的命令提示符中不可用,因?yàn)樘嵘牧钆茖?shí)際上用于不同的登錄會(huì)話。

DOS設(shè)備鏈接的一個(gè)例子是\Global??\C:=>\Device\HarddiskVolume2。在這種情況下,DOS C:驅(qū)動(dòng)器實(shí)際上是指向HarddiskVolume2設(shè)備的符號鏈接。

以下是系統(tǒng)如何處理解析路徑以打開文件的簡要概述。假設(shè)我們調(diào)用WinAPI CreateFile,它將轉(zhuǎn)換后的NT UNICODE_STRING存儲(chǔ)在^{}結(jié)構(gòu)中,并調(diào)用系統(tǒng)函數(shù)NtCreateFile。0:000> g

Breakpoint 1 hit

ntdll!NtCreateFile:

00007ff9`d2023d70 4c8bd1 mov r10,rcx

0:000> !obja @r8

Obja +000000b450f9ec58 at 000000b450f9ec58:

Name is \??\C:\Temp\test.txt

OBJ_CASE_INSENSITIVE

NtCreateFile調(diào)用I/O管理器函數(shù)^{},后者反過來調(diào)用未記錄的對象管理器API ObOpenObjectByName。這是解析路徑的工作。對象管理器以\??\C:\Temp\test.txt開頭。然后它用\Global??\C:Temp\test.txt替換它。接下來它解析到C:符號鏈接,并且必須重新開始(重新解析)最終路徑\Device\HarddiskVolume2\Temp\test.txt。

一旦對象管理器到達(dá)HarddiskVolume2設(shè)備對象,解析就傳遞給I/O管理器,它實(shí)現(xiàn)Device對象類型。I/O的ParseProcedure{}創(chuàng)建File對象和major function codeIRP_MJ_CREATE(打開/創(chuàng)建操作)的I/O Request Packet (IRP)由設(shè)備堆棧處理。這將通過^{}發(fā)送到設(shè)備驅(qū)動(dòng)程序。如果設(shè)備實(shí)現(xiàn)重分析點(diǎn)(例如連接裝入點(diǎn)、符號鏈接等),并且路徑包含重分析點(diǎn),則必須將解析的路徑重新提交給對象管理器,以便從一開始就進(jìn)行分析。

設(shè)備驅(qū)動(dòng)程序?qū)⒃诒闅v目錄時(shí)使用進(jìn)程標(biāo)記(或者如果模擬則使用線程)的SeChangeNotifyPrivilege(幾乎總是存在并啟用)來繞過訪問檢查。但是,最終對設(shè)備和目標(biāo)文件的訪問必須由安全描述符來允許,該描述符通過^{}進(jìn)行驗(yàn)證。除了像FAT32這樣的簡單文件系統(tǒng)不支持文件安全之外。

總結(jié)

以上是生活随笔為你收集整理的python读取路径太长_路径名太长,无法打开?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。