当前位置:  开发笔记 > 编程语言 > 正文

为非现有网络共享加速File.Exists

如何解决《为非现有网络共享加速File.Exists》经验,为你挑选了1个好方法。

我必须检查一组文件路径是否代表现有文件.

它工作正常,除非路径包含不在当前网络上的计算机上的网络共享.在这种情况下,超时需要很长时间(30或60秒).

问题

有没有办法缩短非现有网络共享的超时?(我确信当他们确实存在时他们会很快回答,所以超时1秒就可以了)

有没有其他方法可以解决这个问题,而无需开始缓存并使算法更复杂?(即,我已经知道这些X网络共享不存在,跳过其余的匹配路径)

更新:使用线程工作,但不是特别优雅

public bool pathExists(string path) 
{
    bool exists = true;
    Thread t = new Thread
    (
        new ThreadStart(delegate () 
        {
            exists = System.IO.File.Exists(path); 
        })
    );
    t.Start();
    bool completed = t.Join(500); //half a sec of timeout
    if (!completed) { exists = false; t.Abort(); }
    return exists;
}

此解决方案避免了每次尝试需要一个线程,首先检查哪些驱动器可以访问并将其存储在某处.


专家交换解决方案:

首先,您可以在IsDriveReady函数中设置"超时"值.我把它设置为5秒,但设置它适合任何适合你的.

下面使用3种方法:

    第一个是WNetGetConnection API函数,它获取驱动器的UNC(\ servername\share)

    第二个是我们的主要方法:Button1_Click事件

    第三个是ping服务器的IsDriveReady功能.

这对我很有用!干得好:

'This API Function will be used to get the UNC of the drive
Private Declare Function WNetGetConnection Lib "mpr.dll" Alias _
"WNetGetConnectionA" _
(ByVal lpszLocalName As String, _
ByVal lpszRemoteName As String, _
ByRef cbRemoteName As Int32) As Int32


'This is just a button click event - add code to your appropriate event
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim bIsReady As Boolean = False

    For Each dri As IO.DriveInfo In IO.DriveInfo.GetDrives()

        'If the drive is a Network drive only, then ping it to see if it's ready.
        If dri.DriveType = IO.DriveType.Network Then

            'Get the UNC (\\servername\share) for the 
            '    drive letter returned by dri.Name
            Dim UNC As String = Space(100)
            WNetGetConnection(dri.Name.Substring(0, 2), UNC, 100)

            'Presuming the drive is mapped \\servername\share
            '    Parse the servername out of the UNC
            Dim server As String = _
                 UNC.Trim().Substring(2, UNC.Trim().IndexOf("\", 2) - 2)

            'Ping the server to see if it is available
            bIsReady = IsDriveReady(server)

        Else
            bIsReady = dri.IsReady

        End If

        'Only process drives that are ready
        If bIsReady = True Then
            'Process your drive...
            MsgBox(dri.Name & " is ready:  " & bIsReady)

        End If

    Next

    MsgBox("All drives processed")

End Sub

Private Function IsDriveReady(ByVal serverName As String) As Boolean
    Dim bReturnStatus As Boolean = False

    '***  SET YOUR TIMEOUT HERE  ***
    Dim timeout As Integer = 5    '5 seconds

    Dim pingSender As New System.Net.NetworkInformation.Ping()
    Dim options As New System.Net.NetworkInformation.PingOptions()

    options.DontFragment = True

    'Enter a valid ip address
    Dim ipAddressOrHostName As String = serverName
    Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    Dim buffer As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
    Dim reply As System.Net.NetworkInformation.PingReply = _
                pingSender.Send(ipAddressOrHostName, timeout, buffer, options)

    If reply.Status = Net.NetworkInformation.IPStatus.Success Then
        bReturnStatus = True

    End If

    Return bReturnStatus
End Function

Lieven Keers.. 7

简而言之

    构建可用驱动器列表.

    尝试将driveletter解析为UNC名称.

    尝试ping驱动器.

编辑Bill的评论

如果谷歌不是推荐人,EE不会免费显示答案.EE的链接没有帮助.

OP找到了我在原始答案中提到过的文章,并且非常友好地将解决方案的源代码包含在他的问题中.



1> Lieven Keers..:

简而言之

    构建可用驱动器列表.

    尝试将driveletter解析为UNC名称.

    尝试ping驱动器.

编辑Bill的评论

如果谷歌不是推荐人,EE不会免费显示答案.EE的链接没有帮助.

OP找到了我在原始答案中提到过的文章,并且非常友好地将解决方案的源代码包含在他的问题中.


如果谷歌不是引用者,EE不会免费显示答案.EE的链接没有帮助.
专家交流不是我最喜欢的网站.
推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有