一段时间以来,我一直在为通过 VPN 进行非常缓慢的文件夹枚举而苦恼。尽管 NET 4 改进了一些东西,但我仍然遇到了重大问题。
事实证明(在我编写了对 findfirst/next 的 PINVOKE API 调用之后),问题实际上在于文件夹(或文件)本身的名称。
我一直在测试的文件夹包含一个波浪字符(“~”)——我用它作为我的分隔符之一来识别文件名中的字段——这些文件只由计算机生成和访问,并允许我找到相关文件而无需先打开它们。波浪号不在文件或文件夹的非法字符列表中,也不是用户经常使用的字符,并且波浪号 >31 我认为足够安全。
在我所有的初始测试中它都很好(项目日期为 2009 年),但直到我添加了 VPN 访问。
这个问题的答案是 NET 例程 PATH.GETDIRECTORYNAME 和 DirectoryInfo(x).Name 在使用 (\) UNC 名称时(但仅在那时)分别进入 LA-LA 土地相当长的一段时间。
奇怪的是,文件夹或文件甚至不必存在,所以实际上没有访问任何目录或文件夹,所以这不是 Windows 正在搜索或任何东西,尽管我怀疑它链接到 Windows ~ 短文件名系统。
我在下面添加了测试代码。蜂鸣声用作计时测试的断点。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
beep
Dim x as String = "\\unc\path\foldername\filename.txt"
Dim y as String = "\\unc\path\folder~name\filename.txt"
for tindex as integer = 1 To 500
'Dim m_info =new DirectoryInfo(x).Name
Dim m as String = Path.GetDirectoryName(x)
Next
beep
end
End Sub
如果我在参数中使用 X,我得到的结果 <2ms 如果我使用 Y,它将 >2,500ms
请注意,例如,如果您指定 c:\,问题就会消失 - 大概这对于映射驱动器是正确的(我不使用映射驱动器太害怕勒索软件)
我是否遗漏了过载、开关、窗口设置等,或者这是一个 NET 错误?
最佳答案
我将在这里尝试猜测,因为我目前无法正确测试它。如果我查看 GetDirectoryName 的代码,它调用一个名为 NormalizePath 的函数,他们称之为 PathHelper.TryExpandShortFileName一旦找到波浪号。
// For short file names, we must try to expand each of them as
// soon as possible. We need to allow people to specify a file
// name that doesn't exist using a path with short file names
// in it, such as this for a temp file we're trying to create:
// C:\DOCUME~1\USERNA~1.RED\LOCALS~1\Temp\bg3ylpzp
// We could try doing this afterwards piece by piece, but it's
// probably a lot simpler to do it here.
该函数调用 Win32Native.GetFullPathName 和其他 Win32Native 函数。我认为这就是让你慢下来的原因。它看到 ~ 字符,认为这是一条短路径并试图找到长路径。找不到长路径并处理/忽略该错误。如果它正在处理本地驱动器上的路径,则该进程可能运行得更快,如果它在网络路径上(或者在我的情况下,是不存在的网络路径),则可能运行得更慢。
关于.net - DOT NET 中的文件夹名称访问速度非常慢 - 或文件夹迭代速度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36399296/