在
FtpWebRequest没有递归文件 *** 作(包括下载)任何明确的支持。您必须自己实现递归:
- 列出远程目录
- 迭代条目,下载文件并递归到子目录(再次列出它们,等等)
棘手的部分是从子目录中识别文件。使用。不能以可移植的方式执行此 *** 作
FtpWebRequest。该
FtpWebRequest遗憾的是不支持的
MLSD命令,这是检索目录与FTP协议的文件属性上市的唯一可移植的方法。另请参阅检查FTP服务器上的对象是文件还是目录。
您的选择是:
- 对一定要对文件失败但对目录成功的文件名执行 *** 作(反之亦然)。即,您可以尝试下载“名称”。如果成功,则为文件;如果失败,则为目录。
- 您可能很幸运,在您的特定情况下,您可以通过文件名告诉目录中的文件(即,所有文件都有扩展名,而子目录则没有)
您使用长目录列表(
LIST
command =ListDirectoryDetails
method)并尝试解析服务器特定的列表。许多FTP服务器使用 nix样式的列表,您可以d
在条目的开始处通过来标识目录。但是许多服务器使用不同的格式。下面的示例使用这种方法(假设 nix格式)void DownloadFtpDirectory(string url, NetworkCredential credentials, string localPath)
{
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
listRequest.Credentials = credentials;List<string> lines = new List<string>();using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())using (Stream listStream = listResponse.GetResponseStream())using (StreamReader listReader = new StreamReader(listStream)){ while (!listReader.EndOfStream) { lines.Add(listReader.ReadLine()); }}foreach (string line in lines){ string[] tokens = line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries); string name = tokens[8]; string permissions = tokens[0]; string localFilePath = Path.Combine(localPath, name); string fileUrl = url + name; if (permissions[0] == 'd') { if (!Directory.Exists(localFilePath)) { Directory.CreateDirectory(localFilePath); } DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath); } else { FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl); downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile; downloadRequest.Credentials = credentials; using (FtpWebResponse downloadResponse = (FtpWebResponse)downloadRequest.GetResponse()) using (Stream sourceStream = downloadResponse.GetResponseStream()) using (Stream targetStream = File.Create(localFilePath)) { byte[] buffer = new byte[10240]; int read; while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0) { targetStream.Write(buffer, 0, read); } } }}
}
使用如下功能:
NetworkCredential credentials = new NetworkCredential("user", "mypassword");string url = "ftp://ftp.example.com/directory/to/download/";DownloadFtpDirectory(url, credentials, @"C:targetdirectory");
如果要避免解析特定于服务器的目录列表格式的麻烦,请使用支持该
MLSD命令和/或解析各种
LIST列表格式的第三方库。和递归下载。
例如,使用WinSCP
.NET程序集,您可以通过一次调用来下载整个目录
Session.GetFiles:
// Setup session optionsSessionOptions sessionOptions = new SessionOptions{ Protocol = Protocol.Ftp, HostName = "ftp.example.com", UserName = "user", Password = "mypassword",};using (Session session = new Session()){ // Connect session.Open(sessionOptions); // Download files session.GetFiles("/directory/to/download/*", @"C:targetdirectory*").Check();}
MLSD如果服务器支持,WinSCP在内部使用该命令。如果没有,它将使用该
LIST命令并支持多种不同的列表格式。
默认情况下,该
Session.GetFiles方法是递归的。
(我是WinSCP的作者)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)