加快搜索/阅读从StreamReader

本文关键字:StreamReader 搜索 | 更新日期: 2023-09-27 18:04:29

我试图下载FTP服务器中存在的文件名列表,一旦我检索所有名称,我使用StreamReader对象并尝试搜索所有文件名,以检查该FTP中存在的任何文件所包含的子字符串的存在。

例如,如果文件名像

0000730970 - 0633788104 - 0000730970 - 0633788104. - pdf

0000730970 - 0633789720 - 0000730970 - 0633789720. - pdf

0000730970 - 0633798535 - 0000730970 - 0633798535. - pdf

0000730970 - 0633798536 - 0000730970 - 0633798536. - pdf

0000730970 - 0633804266 - 0000730970 - 0633804266. - pdf

0000730970 - 0633805880 - 0000730970 - 0633805880. - pdf

我将搜索"0633798535"(用破折号分隔的第二个或最后一个子字符串,因为这是我关于该ftp中存在的那些文件的唯一信息,不知道完整的文件名)。下面是我用来做这件事的代码

try{
browseRequest = (FtpWebRequest)FtpWebRequest.Create(ftpAddress);
browseRequest.Credentials = new NetworkCredential(username, password);
browseRequest.UsePassive = true;
browseRequest.UseBinary = true;
browseRequest.KeepAlive = true;
browseRequest.Method = WebRequestMethods.Ftp.ListDirectory;
response = (FtpWebResponse)browseRequest.GetResponse();
responseStream = response.GetResponseStream();
if (responseStream != null)
{
    using (StreamReader reader = new StreamReader(responseStream))
    {
        while (!reader.EndOfStream && !isDownloaded)
        {
            string fileName = reader.ReadLine().ToString();
            if (fileName.Contains(subStringToBeFind)) //search for the first encounter
            {
                //download the file
                isDownloaded = true; //initially false
            }
        }
    }
}
}

这里我使用顺序搜索来查找文件名。但问题是,如果文件数量很大,搜索速度就会变慢,比如对于82000个文件名,如果我要查找最后一个文件,大约需要2分钟的时间。因此,应用程序很慢。所以我需要帮助来加快搜索速度。

加快搜索/阅读从StreamReader

是否有办法使用二分搜索或其他方法来缩短搜索时间?

如果您已经拥有所有数据(并且如果它已经排序,看起来可能在这里),则只能使用二分搜索。我强烈怀疑瓶颈不是这里的Contains方法-我希望它是数据传输。这看起来已经相当有效了,尽管我要做三个更改:

  • 使用ReadLine()在输入结束时返回null而不是使用EndOfStream的事实
  • 使用ReadLine()被声明为返回string的事实-你不需要调用ToString。(这不会影响你的性能,但是很难看。)
  • 对响应和响应流使用using语句。您可能没有问题,因为您已经为读者提供了using语句,但您应该至少为响应本身提供一个。

:

string line;
while (!isDownloaded && (line = reader.ReadLine()) != null)
{
    if (line.Contains(target))
    {
        isDownloaded = true;
    }
}

要验证它真的是网络问题而不是Contains调用,请尝试将两者分开(仅用于诊断目的;您不希望在现实中这样做,因为您希望能够在找到文件后立即停止):

  • 获取所有文件名,并将它们存储在一个文件(或内存中)
  • 查找文件名

为每一步都计时——如果你没有发现第一步几乎花了所有时间,我会很惊讶。使用Contains搜索82000个字符串应该非常非常快。