【问题标题】:FtpWebRequest FTP download with ProgressBarFtpWebRequest 使用 ProgressBar 进行 FTP 下载
【发布时间】:2017-12-29 08:54:09
【问题描述】:

我的代码有效,但ProgressBar 直接跳转到 100% 并且下载将继续。完成后会出现一个消息框来获取信息。

我已经更改了缓冲区大小,但没关系。

我在这里做错了什么?

这是我的代码:

void workerDOWN_DoWork(object sender, DoWorkEventArgs e)
{
    string fileFullPath = e.Argument as String;
    string fileName = Path.GetFileName(fileFullPath);
    string fileExtension = Path.GetExtension(fileName);

    label4.Invoke((MethodInvoker)delegate { label4.Text = "Downloading File.."; });

    string ftpServerIP = "XXX";
    string ftpUserName = "XXX";
    string ftpPassword = "XXX";

    try
    {
        //Datei vom FTP Server downloaden
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
        request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        using (Stream ftpStream = request.GetResponse().GetResponseStream())
        using (Stream fileStream = File.Create(fileFullPath))
        {
            var buffer = new byte[32 * 1024];
            int totalReadBytesCount = 0;
            int readBytesCount;
            while ((readBytesCount = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                fileStream.Write(buffer, 0, readBytesCount);
                totalReadBytesCount += readBytesCount;
                var progress = (int)((float)totalReadBytesCount / (float)fileStream.Length * 100);
                workerDOWN.ReportProgress((int)progress);
                label3.Invoke((MethodInvoker)delegate { label3.Text = progress + " %"; });
            }
        }
    }
    catch (WebException ex)
    {
        FtpWebResponse response = (FtpWebResponse)ex.Response;

        if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
        {
            MessageBox.Show("Datei nicht gefunden!", "Error");
        }
    }
    e.Result = fileFullPath;
}


void workerDOWN_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
     string fileFullPath = e.Result as String;
     string fileName = Path.GetFileName(fileFullPath);

     MessageBox.Show("Download erfolgreich!","Information");

     progressBar1.Value = 0;
     label3.Invoke((MethodInvoker)delegate { label3.Text = " "; });
     label4.Invoke((MethodInvoker)delegate { label4.Text = " "; });      
}

【问题讨论】:

    标签: c# .net ftp progress-bar ftpwebrequest


    【解决方案1】:

    使用带有 WinForms 进度条的FtpWebRequest 进行 FTP 下载的简单示例:

    private void button1_Click(object sender, EventArgs e)
    {
        // Run Download on background thread
        Task.Run(() => Download());
    }
    
    private void Download()
    {
        try
        {
            const string url = "ftp://ftp.example.com/remote/path/file.zip";
            NetworkCredential credentials = new NetworkCredential("username", "password");
    
            // Query size of the file to be downloaded
            WebRequest sizeRequest = WebRequest.Create(url);
            sizeRequest.Credentials = credentials;
            sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;
            int size = (int)sizeRequest.GetResponse().ContentLength;
    
            progressBar1.Invoke(
                (MethodInvoker)(() => progressBar1.Maximum = size));
    
            // Download the file
            WebRequest request = WebRequest.Create(url);
            request.Credentials = credentials;
            request.Method = WebRequestMethods.Ftp.DownloadFile;
    
            using (Stream ftpStream = request.GetResponse().GetResponseStream())
            using (Stream fileStream = File.Create(@"C:\local\path\file.zip"))
            {
                byte[] buffer = new byte[10240];
                int read;
                while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fileStream.Write(buffer, 0, read);
                    int position = (int)fileStream.Position;
                    progressBar1.Invoke(
                        (MethodInvoker)(() => progressBar1.Value = position));
                }
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }
    }
    

    核心下载代码基于:
    Upload and download a binary file to/from FTP server in C#/.NET


    解释为什么你的代码不起作用:

    • 您正在使用目标文件的大小进行计算:fileStream.Length - 它将始终等于 totalReadBytesCount,因此 progress 将始终为 100。
    • 您可能打算使用ftpStream.Length,但无法读取。
    • 基本上使用 FTP 协议,您不知道正在下载的文件的大小。如果你需要知道它,你必须在下载之前明确地查询它。在这里,我使用 WebRequestMethods.Ftp.GetFileSize

    【讨论】:

      【解决方案2】:

      我现在有一个适合我的解决方案。

      首先获得文件大小的想法很棒。 但是当我第一次进行查询以检查文件大小时,Ftp 服务器会抛出一个错误。像这样 FtpWebRequest error: 550 Size not allowed in ASCII mode

      现在我首先下载一个虚拟文件来打开连接.. 见下文

      感谢大家的支持。

      伟大的社区。谢谢。

      void workerDOWN_DoWork(object sender, DoWorkEventArgs e)
              {
                  string fileFullPath = e.Argument as String;
                  string fileName = Path.GetFileName(fileFullPath);
                  string fileExtension = Path.GetExtension(fileName);
      
                  label4.Invoke((MethodInvoker)delegate { label4.Text = "Downloading File.."; });
      
                  //FTP Download und Delete
                  string ftpServerIP = "XXX";
                  string ftpUserName = "XXXX";
                  string ftpPassword = "XXXXX";
      
                  try
                  {
                      // dummy download ftp connection for ftp server bug
                      FtpWebRequest DummyRequest = (FtpWebRequest)WebRequest.Create(("ftp://" + ftpServerIP + "/anyfile"));
                      DummyRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
                      DummyRequest.Method = WebRequestMethods.Ftp.DownloadFile;
                      using (Stream ftpStream = DummyRequest.GetResponse().GetResponseStream())
                      using (Stream fileStream = File.Create(Path.GetDirectoryName(Application.ExecutablePath) + "\\anyfile"))
                      {
                          ftpStream.CopyTo(fileStream);
                      }
                      //delete downloaded test file
                      File.Delete(Path.GetDirectoryName(Application.ExecutablePath) + "\\anyfile");
      
                      // Query size of the file to be downloaded
                      FtpWebRequest sizeRequest = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
                      sizeRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
                      sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;
                      var fileSize = sizeRequest.GetResponse().ContentLength;
      
                      //file download
                      FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
                      request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
                      request.Method = WebRequestMethods.Ftp.DownloadFile;
                      using (Stream ftpStream = request.GetResponse().GetResponseStream())
                      using (Stream fileStream = File.Create(fileFullPath))
                      {
                          var buffer = new byte[32 * 1024];
                          int totalReadBytesCount = 0;
                          int readBytesCount;
                          while ((readBytesCount = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                          {
                              fileStream.Write(buffer, 0, readBytesCount);
                              totalReadBytesCount += readBytesCount;
                              var progress = (int)((float)totalReadBytesCount / (float)fileSize * 100);
                              workerDOWN.ReportProgress((int)progress);
                              label3.Invoke((MethodInvoker)delegate { label3.Text = progress + " %"; });
                          }
                      }
      
                      // delete file on ftp server
                      FtpWebRequest Delrequest = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
                      Delrequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
                      Delrequest.Method = WebRequestMethods.Ftp.DeleteFile;
                      FtpWebResponse Delresponse = (FtpWebResponse)Delrequest.GetResponse();
                      Delresponse.Close();
      
                      // message file deleted
                      richTextBox1.Invoke((MethodInvoker)delegate { richTextBox1.AppendText("System: " + fileName + " wurde auf dem Server gelöscht." + Environment.NewLine); });
      
                  }
                  catch (WebException ex)
                  {
                      FtpWebResponse response = (FtpWebResponse)ex.Response;
      
                      if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
                      {
      
                          MessageBox.Show("Datei nicht gefunden!", "Error");
                      } 
                  }
      
                  e.Result = fileFullPath;
      
              }
      
      
              void workerDOWN_ProgressChanged(object sender, ProgressChangedEventArgs e)
              {
                  progressBar1.Value = e.ProgressPercentage;
              }
      
              void workerDOWN_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
              {
                   string fileFullPath = e.Result as String;
                   string fileName = Path.GetFileName(fileFullPath);
      
                   MessageBox.Show("Download erfolgreich!","Information");
      
                   progressBar1.Value = 0;
                   label3.Invoke((MethodInvoker)delegate { label3.Text = " "; });
                   label4.Invoke((MethodInvoker)delegate { label4.Text = " "; });
      
      
              }
      

      【讨论】:

        【解决方案3】:

        在不确切知道ProgressChanged 事件处理程序中的代码做什么的情况下,我认为您无意中将括号放在* 100 之后的进度计算中。

        你可以试试这个:

        var progress = (int)((float)totalReadBytesCount / (float)fileStream.Length) * 100;
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 1970-01-01
        • 2011-07-20
        • 2012-09-13
        • 1970-01-01
        相关资源
        最近更新 更多