【问题标题】:C# Upload whole directory using FTPC# 使用 FTP 上传整个目录
【发布时间】:2012-10-30 00:04:40
【问题描述】:

我要做的是在 C# (C Sharp) 中使用 FTP 上传网站。所以我需要上传一个文件夹中的所有文件和文件夹,保持它的结构。我正在使用这个 FTP 类:http://www.codeproject.com/Tips/443588/Simple-Csharp-FTP-Class 进行实际上传。

我得出的结论是,我需要编写一个递归方法,遍历主目录的每个子目录并上传其中的所有文件和文件夹。这应该将我的文件夹复制到 FTP。问题是......我不知道如何编写这样的方法。我以前写过递归方法,但我是 FTP 部分的新手。

这是我目前所拥有的:

private void recursiveDirectory(string directoryPath)
    {
        string[] filePaths = null;
        string[] subDirectories = null;

        filePaths = Directory.GetFiles(directoryPath, "*.*");
        subDirectories = Directory.GetDirectories(directoryPath);

        if (filePaths != null && subDirectories != null)
        {
            foreach (string directory in subDirectories)
            {
                ftpClient.createDirectory(directory);
            }
            foreach (string file in filePaths)
            {
                ftpClient.upload(Path.GetDirectoryName(directoryPath), file);
            }
        }
    }

但它远未完成,我不知道如何继续。我敢肯定,比我更需要知道这一点!在此先感谢:)

哦……如果它也报告它的进度就好了:)(我正在使用进度条)

编辑: 可能还不清楚...如何使用 FTP 上传包含所有子目录和文件的目录?

【问题讨论】:

  • 让我们先解决一个简单的问题。编写一个方法,循环遍历父文件夹中的每个文件夹,并在相关网站上创建它。一旦你这样做了,上传每个文件夹中的每个文件应该很容易。你没有做足够的事情让我们帮助你。我不敢相信你有勇气提出功能要求.....
  • 要创建进度条,您需要获取所有需要上传的文件。我会将文件路径存储在列表中。然后循环遍历文件路径以将它们上传到 FTP 服务器。每次上传后更新进度。通过使用文件路径存储文件的大小可以实现更准确的条形图。然后,随着每个文件的上传,进度会增加文件的大小。如果您需要,我可以在后面添加一个示例。

标签: c# recursion upload ftp directory


【解决方案1】:

除非您这样做是为了娱乐或自我​​提升,否则请使用商业模块。我可以从Chilkat 推荐一个,但我相信还有其他的。

注意:我很确定这确实解决了上述问题,我正在尝试使用 C# (C Sharp) 中的 FTP 上传网站。 em>

【讨论】:

    【解决方案2】:

    我编写了一个 FTP 类,并将它包装在一个 WinForms 用户控件中。你可以在文章An FtpClient Class and WinForm Control看到我的代码。

    【讨论】:

      【解决方案3】:

      问题解决了! :)

      好的,所以我设法编写了方法 myslef。如果有人需要,请随时复制:

      private void recursiveDirectory(string dirPath, string uploadPath)
          {
              string[] files = Directory.GetFiles(dirPath, "*.*");
              string[] subDirs = Directory.GetDirectories(dirPath);
      
              foreach (string file in files)
              {
                  ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
              }
      
              foreach (string subDir in subDirs)
              {
                  ftpClient.createDirectory(uploadPath + "/" + Path.GetFileName(subDir));
                  recursiveDirectory(subDir, uploadPath + "/" + Path.GetFileName(subDir));
              }
          }
      

      效果很好:)

      【讨论】:

      • 如果您提到您使用外部库来执行该代码,它会起作用,其中包括许多不是您制作的其他代码。
      • 他在问题中做到了。但是,是的,我也想要冗余,而不必寻找链接。
      • 这最终会远程创建所有文件和目录,但所有文件的文件大小均为 0B。 ???
      • 奇怪。我不知道该课程如何适用于任何人。我可以通过将FileMode 值更改为Open 来修复他们的upload() 方法:FileStream localFileStream = new FileStream(localFile, FileMode.Open);
      【解决方案4】:

      我编写了一个可重用类来将整个目录上传到 Windows 服务器上的 ftp site
      该程序还重命名了该文件夹的旧版本(我使用它来将我的 Windows 服务程序上传到服务器)。 也许有些人需要这个:

      class MyFtpClient
      {
          protected string FtpUser { get; set; }
          protected string FtpPass { get; set; }
          protected string FtpServerUrl { get; set; }
          protected string DirPathToUpload { get; set; }
          protected string BaseDirectory { get; set; }
      
          public MyFtpClient(string ftpuser, string ftppass, string ftpserverurl, string dirpathtoupload)
          {
              this.FtpPass = ftppass;
              this.FtpUser = ftpuser;
              this.FtpServerUrl = ftpserverurl;
              this.DirPathToUpload = dirpathtoupload;
              var spllitedpath = dirpathtoupload.Split('\\').ToArray();
              // last index must be the "base" directory on the server
              this.BaseDirectory = spllitedpath[spllitedpath.Length - 1];
          }
      
      
          public void UploadDirectory()
          {
              // rename the old folder version (if exist)
              RenameDir(BaseDirectory);
              // create a parent folder on server
              CreateDir(BaseDirectory);
              // upload the files in the most external directory of the path
              UploadAllFolderFiles(DirPathToUpload, BaseDirectory);
              // loop trough all files in subdirectories
      
      
      
              foreach (string dirPath in Directory.GetDirectories(DirPathToUpload, "*",
              SearchOption.AllDirectories))
              {
                  // create the folder
                  CreateDir(dirPath.Substring(dirPath.IndexOf(BaseDirectory), dirPath.Length - dirPath.IndexOf(BaseDirectory)));
      
                  Console.WriteLine(dirPath.Substring(dirPath.IndexOf(BaseDirectory), dirPath.Length - dirPath.IndexOf(BaseDirectory)));
                  UploadAllFolderFiles(dirPath, dirPath.Substring(dirPath.IndexOf(BaseDirectory), dirPath.Length - dirPath.IndexOf(BaseDirectory))
              }
          }
      
          private void UploadAllFolderFiles(string localpath, string remotepath)
          {
              string[] files = Directory.GetFiles(localpath);
              // get only the filenames and concat to remote path
              foreach (string file in files)
              {
                  // full remote path
                  var fullremotepath = remotepath + "\\" + Path.GetFileName(file);
                  // local path
                  var fulllocalpath = Path.GetFullPath(file);
                  // upload to server
                  Upload(fulllocalpath, fullremotepath);
              }
      
          }
      
          public bool CreateDir(string dirname)
          {
              try
              {
                  WebRequest request = WebRequest.Create("ftp://" + FtpServerUrl + "/" + dirname);
                  request.Method = WebRequestMethods.Ftp.MakeDirectory;
                  request.Proxy = new WebProxy();
                  request.Credentials = new NetworkCredential(FtpUser, FtpPass);
                  using (var resp = (FtpWebResponse)request.GetResponse())
                  {
                      if (resp.StatusCode == FtpStatusCode.PathnameCreated)
                      {
                          return true;
                      }
                      else
                      {
                          return false;
                      }
                  }
              }
      
              catch
              {
                  return false;
              }
          }
      
          public void Upload(string filepath, string targetpath)
          {
      
              using (WebClient client = new WebClient())
              {
                  client.Credentials = new NetworkCredential(FtpUser, FtpPass);
                  client.Proxy = null;
                  var fixedpath = targetpath.Replace(@"\", "/");
                  client.UploadFile("ftp://" + FtpServerUrl + "/" + fixedpath, WebRequestMethods.Ftp.UploadFile, filepath);
              }
          }
      
          public bool RenameDir(string dirname)
          {
              var path = "ftp://" + FtpServerUrl + "/" + dirname;
              string serverUri = path;
      
              try
              {
                  FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
                  request.Method = WebRequestMethods.Ftp.Rename;
                  request.Proxy = null;
                  request.Credentials = new NetworkCredential(FtpUser, FtpPass);
                  // change the name of the old folder the old folder
                  request.RenameTo = DateTime.Now.ToString("yyyyMMddHHmmss"); 
                  FtpWebResponse response = (FtpWebResponse)request.GetResponse();
      
                  using (var resp = (FtpWebResponse)request.GetResponse())
                  {
                      if (resp.StatusCode == FtpStatusCode.FileActionOK)
                      {
                          return true;
                      }
                      else
                      {
                          return false;
                      }
                  }
              }
              catch
              {
                  return false;
              }
          }
      }
      

      创建该类的实例:

      static void Main(string[] args)
      {
          MyFtpClientftp = new MyFtpClient(ftpuser, ftppass, ftpServerUrl, @"C:\Users\xxxxxxxxxxx");
          ftp.UploadDirectory();
          Console.WriteLine("DONE");
          Console.ReadLine();
      }
      

      【讨论】:

      • 太棒了!这是迄今为止我找到的最好的解决方案。它只是缺少目标文件夹以使其变得更好。