【问题标题】:How to download FTP files with automatic resume in case of disconnect如何在断开连接的情况下自动恢复下载 FTP 文件
【发布时间】:2011-09-13 22:33:06
【问题描述】:

我可以下载 FTP 文件,但下载代码没有恢复功能和多部分文件下载。因为有大于 500 MB 的文件,我不能连续下载它们,因为连接被关闭,它从头开始下载。如果我的代码断开连接,我希望我的代码成为恢复工具。

我使用的代码是:

public string[] GetFileList()
{
    string[] downloadFiles;
    StringBuilder result = new StringBuilder();
    FtpWebRequest reqFTP;
    try
    {
        reqFTP = (FtpWebRequest)FtpWebRequest.Create(
            new Uri("ftp://" + ftpServerIP + "/"));
        reqFTP.UseBinary = true;
        reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
        WebResponse response = reqFTP.GetResponse();
        StreamReader reader = new StreamReader(response.GetResponseStream());
        //MessageBox.Show(reader.ReadToEnd());
        string line = reader.ReadLine();
        while (line != null)
        {
            result.Append(line);
            result.Append("\n");
            line = reader.ReadLine();
        }
        result.Remove(result.ToString().LastIndexOf('\n'), 1);
        reader.Close();
        response.Close();
        //MessageBox.Show(response.StatusDescription);
        return result.ToString().Split('\n');
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message);
        downloadFiles = null;
        return downloadFiles;
    }
}

private void Download(string filePath, string fileName)
{
    FtpWebRequest reqFTP;
    try
    {
        //filePath = <<The full path where the file is to be created.>>, 
        //fileName = <<Name of the file to be created
        //             (Need not be the name of the file on FTP server).>>
        FileStream outputStream =
            new FileStream(filePath + "\\" + fileName, FileMode.Create);

        reqFTP = (FtpWebRequest)FtpWebRequest.Create(
            new Uri("ftp://" + ftpServerIP + "/" + fileName));
        reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
        reqFTP.UseBinary = true;
        reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
        FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
        Stream ftpStream = response.GetResponseStream();
        long cl = response.ContentLength;
        int bufferSize = 2048;
        int readCount;
        byte[] buffer = new byte[bufferSize];

        readCount = ftpStream.Read(buffer, 0, bufferSize);
        while (readCount > 0)
        {
            outputStream.Write(buffer, 0, readCount);
            readCount = ftpStream.Read(buffer, 0, bufferSize);
        }

        ftpStream.Close();
        outputStream.Close();
        response.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

【问题讨论】:

    标签: c# .net ftp ftpwebrequest


    【解决方案1】:

    开始下载之前,请检查本地文件系统上是否存在该文件。如果存在,则获取大小并将其用于FtpWebRequest 对象的ContentOffset 成员。不过,FTP 服务器可能不支持此功能。

    【讨论】:

      【解决方案2】:

      使用FtpWebRequest 恢复FTP 下载的本机实现:

      bool resume = false;
      do
      {
          try
          {
              FileMode mode = resume ? FileMode.Append : FileMode.Create;
              resume = false;
              using (Stream fileStream = File.Open(@"C:\local\path\file.dat", mode))
              {
                  var url = "ftp://ftp.example.com/remote/path/file.dat";
                  FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
                  request.Credentials = new NetworkCredential("username", "password");
                  request.Method = WebRequestMethods.Ftp.DownloadFile;
                  request.ContentOffset = fileStream.Position;
                  using (Stream ftpStream = request.GetResponse().GetResponseStream())
                  {
                      ftpStream.CopyTo(fileStream);
                  }
              }
          }
          catch (WebException)
          {
              resume = true;
          }
      }
      while (resume);
      

      或者使用可以自动恢复传输的 FTP 库。

      例如WinSCP .NET assembly 可以。有了它,可恢复的下载就变得如此简单:

      // Setup session options
      var sessionOptions = new WinSCP.SessionOptions
      {
          Protocol = Protocol.Ftp,
          HostName = "ftp.example.com",
          UserName = "user",
          Password = "mypassword"
      };
      
      using (var session = new Session())
      {
          // Connect
          session.Open(sessionOptions);
      
          // Resumable download
          session.GetFileToDirectory("/home/user/file.zip", @"C:\path");
      }
      

      (我是 WinSCP 的作者)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-02
        • 1970-01-01
        • 1970-01-01
        • 2012-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多