C# 使用 ftpRequest 获取完整的文件列表很慢
Posted
技术标签:
【中文标题】C# 使用 ftpRequest 获取完整的文件列表很慢【英文标题】:C# Getting a complete file list using ftpRequest is slow 【发布时间】:2010-02-20 16:25:25 【问题描述】:我想获取 FTP 服务器上每个文件的文件名、文件大小和最后修改时间,然后用它填充一个 listView。
在我切换 FTP 主机之前它运行良好,现在它真的很慢,尽管新主机在真正的 FTP 客户端中速度一样快。
有什么明显的原因吗?
另外,真的有必要每次都发送登录凭据吗?
我使用第一种方法来获取一个字符串数组,然后遍历它并在每个项目上使用第二种方法来获取文件大小:
public static string[] GetFileList()
string[] downloadFiles;
StringBuilder result = new StringBuilder();
FtpWebRequest request;
try
request = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://mysite.se/"));
request.UseBinary = true;
request.Credentials = new NetworkCredential(settings.Username, settings.Password);
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.UseBinary = true;
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
while (line != null)
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
// to remove the trailing '\n'
result.Remove(result.ToString().LastIndexOf('\n'), 1);
reader.Close();
response.Close();
return result.ToString().Split('\n');
catch (Exception ex)
System.Windows.Forms.MessageBox.Show(ex.Message);
downloadFiles = null;
return downloadFiles;
public static int GetFileSize(string file)
//MessageBox.Show("getting filesize...");
StringBuilder result = new StringBuilder();
FtpWebRequest request;
try
request = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://mysite.se/" + file));
request.UseBinary = true;
request.Credentials = new NetworkCredential(settings.Username, settings.Password);
request.Method = WebRequestMethods.Ftp.GetFileSize;
int dataLength = (int)request.GetResponse().ContentLength;
return dataLength;
catch (Exception ex)
//System.Windows.Forms.MessageBox.Show(ex.Message);
return 1337;
【问题讨论】:
【参考方案1】:问题是每个 GetFileSize 调用都必须重新连接到服务器并发出文件大小请求。如果您可以设置使用单个持久连接,那么您将节省连接时间,但仍会花费大量时间为每个文件发送请求并等待响应。
(编辑:可能已经是这种情况了。MSDN 说:Multiple FtpWebRequests reuse existing connections, if possible.)
如果您使用 ListDirectoryDetails 而不是 ListDirectory,那么服务器可能会连同每个文件名一起发送更多信息(文件大小、权限等)。这不会比只做 ListDirectory 花费任何时间,而且您可以从每一行中提取名称和大小并存储大小以供以后使用。
但是,不同的服务器可能会以不同的格式发送信息,有些可能根本不发送大小信息,因此如果您需要您的程序可靠地使用任何 FTP 服务器,这可能无济于事。
【讨论】:
【参考方案2】:不是一个正确甚至是好的答案:
这是一个展示其工作原理的 PowerShell 测试示例:
$request=[System.Net.FtpWebRequest]::Create('ftp://ftp.hp.com/control/SavvisLoad.whp-ftp.xml')
$request.UseBinary=$false
$request.Method=[System.Net.WebRequestMethods+Ftp]::GetDateTimestamp
$request.GetResponse()
这使用 HP 公共服务器并显示如何获取文件大小。
ListDirectoryDetails 获取文件夹信息。
上面最大的错误是模式设置为二进制。所有目录列表和文件信息都必须使用文本模式。
【讨论】:
【参考方案3】:这是获得目录列表的一种行之有效且快速的方法。可以使用 PowerShell 按原样进行测试。
[System.Net.FtpWebRequest]$request = [System.Net.WebRequest]::Create("ftp://ftp.hp.com/control")
#$request.Credentials=New-Object System.Net.NetworkCredential('Anonymous','johnjones3@msn.com')
$request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectoryDetails
$request.UseBinary=$false
$response=$request.GetResponse()
$stream=$response.GetResponseStream()
$b=new-object byte[] 1024
$stream.Read($b,0,$b.Count)
$b|%$s+=[char]$_
$s
【讨论】:
以上是关于C# 使用 ftpRequest 获取完整的文件列表很慢的主要内容,如果未能解决你的问题,请参考以下文章