2017-07-23 3 views
1

Mein Code funktioniert, aber die ProgressBar springt direkt auf 100% und der Download wird fortgesetzt. Wenn es fertig ist dann kommt eine MessageBox um eine Info zu machen.FtpWebRequest FTP-Download mit ProgressBar

Ich habe bereits die Puffergröße geändert, aber das spielt keine Rolle.

Was mache ich hier falsch?

Hier ist mein Code:

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 = " "; });  
} 
+0

Können Sie Ihren Fortschritt geändert Ereignis? – FortyTwo

Antwort

0

Ohne genau zu wissen, was Ihr Code in den ProgressChanged Eventhandler tut, glaube ich, dass Sie unbeabsichtigt nach * 100 die Klammern in Ihrem Fortschritt Rechnung gestellt.

Sie konnten dieses versuchen:

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

Ich ging davon aus, dass Sie dort den Fortschrittsbalken aktualisieren, den Sie erwähnt haben. (siehe: https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.reportprogress(v=vs.110).aspx) - ReportProgress löst dieses Ereignis aus. –

1

Trivial Beispiel Download FTP FtpWebRequest mit WinForms Fortschrittsbalken mit:

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); 
    } 
} 

enter image description here

Der Downloadcode Kern basiert auf:
Upload and download a binary file to/from FTP server in C#/.NET


Um zu erklären, warum Ihr Code nicht funktioniert:

  • Sie sind für die Berechnung Größe der Zieldatei: fileStream.Length - Es wird immer daher gleich zu totalReadBytesCount, wird die progress immer 100
  • Sie wollten wahrscheinlich ftpStream.Length verwenden, aber das kann nicht gelesen werden.
  • Grundsätzlich mit FTP-Protokoll, wissen Sie nicht die Größe der Datei, die Sie herunterladen. Wenn Sie es wissen müssen, müssen Sie es explizit vor dem Download abfragen. Hier verwende ich die WebRequestMethods.Ftp.GetFileSize dafür.
0

Ich habe jetzt eine Lösung, die für mich arbeitet.

Die Idee, zuerst die Dateigröße zu bekommen, war großartig. Aber wenn ich zuerst eine Abfrage zur Überprüfung der Dateigröße macht, löst der FTP-Server einen Fehler aus. Gefallen Sie diese FtpWebRequest error: 550 Size not allowed in ASCII mode

Jetzt zuerst herunterladen i eine Dummy-Datei, um die Verbindung zu öffnen .. Siehe unten

Dank an alle für die Unterstützung.

Große Gemeinschaft. Vielen Dank.

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 = " "; }); 


     }