C#通过FTP下载所有文件和子目录

C#通过FTP下载所有文件和子目录,第1张

C#通过FTP下载所有文件和子目录

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的作者)



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4894816.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存