我对C#中的ftp库有疑问。我需要从ftp服务器下载9000个txt文件。 Station.ToUpper()是文件名,因此对于每个文件我都需要一个新的ftp连接。对于一个文件,它需要大约一秒钟。 txt文件包含两行。所以对于所有文件大约需要一个半小时。是否有更好/更快的解决方案?
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddress + station.ToUpper());
//request.UsePassive = false;
request.Method = WebRequestMethods.Ftp.DownloadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("anonymous", "janeDoe@contoso.com");
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
答案 0 :(得分:2)
除了你没有在你的流或响应对象上调用Dispose()
之外,你在这段代码中做错了。首先要做的是确保你不会以某种方式耗尽客户端上的资源或其他东西。
除此之外,这里没有太多选项,很大程度上取决于你在服务器端可以做些什么。
首先,您可以尝试使用线程一次下载一堆文件。您需要尝试这会如何影响您的吞吐量。它可能会线性缩放一段时间,然后下降。如果你打开太多的连接,你可能会激怒服务器的维护者,或者它可能会开始拒绝你的连接。保守。
最理想的是,文件将在服务器上压缩(.ZIP或.TGZ)。如果您对流程没有更多控制权,这可能不是一个选项。
答案 1 :(得分:2)
使用MGET
命令避免每次重新建立连接。 System.Net
客户端不支持MGET
,因此您必须使用第三方库或脚本ftp.exe
。无论您选择哪个客户端,FTP日志都如下所示:
USER anonymous
PASS janeDoe@contoso.com
CWD path/to/file
// to get 3 named files
MGET file1.txt file2.txt file3.txt
// or to get all files matching a pattern
MGET *.txt
文件传输将使用相同的控制会话,避免登录和其他网络开销。
可能感兴趣的一个库是FTPLib,这可以避免在每个命令上拆除通道。但请注意,因为FTPLib基于wininet
,不允许在NT服务中使用。
我还会看一下LumiSoft,一个带有友好许可证的开源项目,DotNetFtpLib,虽然我既不使用也不能说出他们的稳定性或功能集。在脚本方面,请查看"Using FTP Batch Scripts"。