在DOT NET中访问非常慢的文件夹名称 - 或文件夹迭代速度问题

时间:2016-04-04 09:46:53

标签: .net vb.net file path directory

我已经在VPN上进行了非常缓慢的文件夹枚举摔跤一段时间了。即使NET 4改进了东西,我仍然遇到了重大问题。

事实证明(在我将PINVOKE API调用写入findfirst / next之后),问题实际上存在于文件夹(或文件)本身的名称中。

我测试过的文件夹中包含一个波形符(“〜”) - 我用它作为我的分隔符之一来识别文件名中的字段 - 这些文件只是计算机生成和访问,允许我查找相关文件没有先打开它们。代字号不在文件或文件夹的非法字符列表中,并且不是用户经常使用的字符,并且> 31我认为足够安全。

在我的所有初步测试中都很好(项目日期到2009年),但直到我添加了VPN访问。

这个问题的答案是,当使用(\)UNC名称时(但只有这样),NET例程PATH.GETDIRECTORYNAME和DirectoryInfo(x).Name每个都进入LA-LA域一段时间。 / p>

奇怪的是,文件夹或文件甚至不必存在,因此实际上没有访问任何dirves或文件夹,所以它不是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:\,例如问题就会消失 - 大概这对于映射驱动器是正确的(我不会使用映射驱动器太害怕ransomeware)

我是否错过了过载,开关,窗口设置等,或者这是一个NET错误?

1 个答案:

答案 0 :(得分:1)

我要尝试猜测,因为此刻我无法正确测试。如果我查看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函数。我认为这会减慢你的速度。它看到〜字符,认为它是一条短路径并试图找到长路径。找不到长路径并且有句柄/忽略该错误。如果它正在处理本地驱动器上的路径,那么该进程可能运行得更快,如果它在网络路径上(或者在我的情况下,是一个不存在的网络路径),则运行速度会慢一些。