更快的DirectoryExists功能?

时间:2009-09-17 13:33:32

标签: delphi networking delphi-2009

我用

DirectoryExists (const PathName : String);

检查是否可以从计算机访问目录。但如果目录不存在且路径名是网络路径,即

\\computer1\Data

该方法需要很长时间才能返回。

必须有一种更快的方法来确定无法访问网络文件夹。或者我可以配置DirectoryExists在内部使用的一些超时参数(我查看了源代码,但它只是委托给kernel32中定义的GetFileAttributes)?

有什么想法吗?

8 个答案:

答案 0 :(得分:19)

没有更快的方法:

当该共享不可用时,任何访问远程共享上任何内容的函数都将超时。

如果您的超时原因是自动断开共享,那么这些链接可能对您有所帮助:

如果应用程序可以在没有完成检查的情况下继续,那么您可以将检查放在一个单独的线程中,并且在检查完成后,您可以在UI中更新您的状态。

请注意,当您尝试使用多线程方式时,您必须反驳代码,这样就不会出现竞争条件和内存泄漏。超时与异常相结合通常会使这成为一项艰巨的任务。

答案 1 :(得分:6)

C#也有同样的问题: How to avoid network stalls in GetFileAttributes?

正如codymanix所说,使用线程。上面的链接将向您展示如何使用C#中的代理进行操作。不知道Delphi,但也许您知道如何转换代码?

答案 2 :(得分:5)

如果你测试了很多目录,你应该使用线程来并行执行所有查询,因为对于网络共享来说,通常需要很长的时间。

答案 3 :(得分:3)

这是最好的方法。您可以添加一些代码来ping机器以确保其存在,但是这仍然会使例程失败,因为现在许多计算机都设置了软件防火墙来忽略ping请求,以及请求的共享可能没有存在。

此外,在某些机器上,如果UNC路径在本地计算机上并且本地计算机没有活动网卡(例如在“飞机”模式下使用Wi-Fi断开连接的笔记本电脑),则UNC请求也将失败。

答案 4 :(得分:2)

在类似你规定的情况下,我首先向服务器添加了ICMP ping。如果服务器没有响应ping,我认为它已关闭。您可以自己决定在ping上使用哪个超时,因此您可以将其设置为比尝试打开文件共享时内部使用的超时短得多。

答案 5 :(得分:2)

我使用以下代码......

private delegate bool DirectoryExistsDelegate(string folder);

bool DirectoryExistsTimeout(string path, int millisecondsTimeout)
{
    try
    {
        DirectoryExistsDelegate callback = new DirectoryExistsDelegate(Directory.Exists);
        IAsyncResult result = callback.BeginInvoke(path, null, null);

        if (result.AsyncWaitHandle.WaitOne(millisecondsTimeout, false))
        {
            return callback.EndInvoke(result);
        }
        else
        {
            callback.EndInvoke(result);  // Needed to terminate thread?

            return false;
        }
    }

    catch (Exception)
    {
        return false;
    }
}

...这允许我拥有Directory.Exist的超时版本。我称之为......

bool a = DirectoryExistsTimeout("\\\\machine\\folder", 5000);

这可以满足您的需求吗?


为了安全/合法,你需要调用“callback.EndInvoke(result);”但是在异步完成之前调用它会锁定,这会破坏代码的对象。也许这需要在代码结束时完成 - 退出可能吗?

答案 6 :(得分:0)

如果两台计算机都在同一个域上,它将在处理共享时加快文件操作。

答案 7 :(得分:0)

此功能非常适合我: > {"created_date":"2019-02-03T18:35:59.514Z","s_type":"BLOCK","datetime":"20181121_070000","ds_ser":"443551","ven":"abc","cou_name":"USA","c_name":"Piscataway","d_name":"Piscataway","dv_name":"USPSCG","p_name":"443551-CK","redTime":0.0,"wrTime":0.0,"tRate":0,"MTRate":0} > {"created_date":"2019-02-03T18:35:59.514Z","s_type":"BLOCK","datetime":"20181121_070000","ds_ser":"443551","ven":"abc","cou_name":"USA","c_name":"Piscataway","d_name":"Piscataway","dv_name":"USPSCG4","p_name":"443551-CF","redTime":0.0,"wrTime":0.0,"tRate":0,"MTRate":0}
它使用Threading,是NetDirectoryExists(Path, Timeout)

的完美替代方案

用法:
TDirectory.Exists(Path)
if NetDirectoryExists('\\computer1\Data', 1000) then ...

如果存在文件夹,则该功能仅需要几毫秒,与不存在的文件夹(if NetDirectoryExists('C:\Folder', 500) then ...)相同。如果它是无法访问的网络路径(C:\NotExisting),那么它将消耗第二个参数给定的毫秒数。

\\ServerNotReady\C$