首页 > 后端开发 > C++ > 如何在C#中通过FTP递归下载所有文件和子目录?

如何在C#中通过FTP递归下载所有文件和子目录?

DDD
发布: 2025-01-12 14:56:43
原创
541 人浏览过

How to Recursively Download All Files and Subdirectories via FTP in C#?

C# FTP递归下载文件和子目录

使用FTP自动同步文件时,经常会遇到下载文件和子目录的难题。由于将文件夹视为要下载的文件,这通常伴随着550错误。

识别文件与目录

FTP 本身并没有清晰地区分文件和目录。因此,需要使用其他方法来识别它们的类型。

  • 尝试下载文件:如果尝试下载“文件”失败,则可能是目录。
  • 文件扩展名:当特定目录中的文件的文件扩展名一致时,这可以用来区分文件和目录。
  • 服务器特定的目录列表:解析服务器对目录列表命令(例如,LIST)的响应。某些服务器使用特定字符或符号来指示目录。

递归文件下载

要下载所有文件(包括子目录中的文件),请按照以下步骤操作:

  1. 列出远程目录并检索目录列表。
  2. 遍历列表并区分文件和目录。
  3. 对于文件,照常下载它们。
  4. 对于目录,递归重复步骤 1-3 以检索子目录中的文件。

代码实现

以下代码示例演示了使用 FtpWebRequest 类进行递归文件下载,假设使用的是 *nix 风格的目录列表:

<code class="language-csharp">using System;
using System.IO;
using System.Net;

public class FtpDownload
{
    public static void DownloadFtpDirectory(string url, NetworkCredential credentials, string localPath)
    {
        FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
        listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
        listRequest.Credentials = credentials;

        var lines = new System.Collections.Generic.List<string>();

        using (var listResponse = (FtpWebResponse)listRequest.GetResponse())
        using (Stream listStream = listResponse.GetResponseStream())
        using (var 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);
                    }
                }
            }
        }
    }
}</code>
登录后复制

替代库

为了增强功能并支持 MLSD 命令,请考虑使用 WinSCP.NET 等第三方库。此库简化了递归下载并支持各种服务器特定的目录列表格式。

<code class="language-csharp">using System;
using System.IO;
using WinSCP;

public class FtpDownloadWithLibrary
{
    public static void DownloadFtpDirectory(string url, NetworkCredential credentials, string localPath)
    {
        // 设置会话选项
        SessionOptions sessionOptions = new SessionOptions
        {
            Protocol = Protocol.Ftp,
            HostName = host, // 请替换为你的主机名
            UserName = user, // 请替换为你的用户名
            Password = password, // 请替换为你的密码
        };

        using (Session session = new Session())
        {
            // 连接
            session.Open(sessionOptions);

            // 下载文件
            session.GetFiles(url, localPath).Check();
        }
    }
}</code>
登录后复制

请注意,FtpDownloadWithLibrary 示例中需要替换 host, user, password 为你的实际 FTP 服务器信息。 并且你需要安装 WinSCP.NET 库。

以上是如何在C#中通过FTP递归下载所有文件和子目录?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板