FtpWebRequest téléchargement FTP avec ProgressBar

mon code fonctionne, mais le ProgressBar saute directement à 100% et le téléchargement va continuer. Quand il est terminé vient alors une boîte de messagerie pour prendre une Info.

j'ai déjà changé la taille du tampon, mais ça n'a pas d'importance.

Qu'est-ce que je fais de mal ici?

Voici mon 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 = " "; });      
}
2
demandé sur Martin Prikryl 2017-07-23 22:46:38

3 réponses

exemple Trivial de téléchargement FTP à l'aide de FtpWebRequest avec WinForms barre de progression:

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

le code de téléchargement de base est basé sur:

télécharger un fichier binaire depuis/vers le serveur FTP dans C# / .NET


pour expliquer pourquoi votre code ne fonctionne pas:

  • vous utilisez la taille du fichier cible pour le calcul: fileStream.Length - il sera toujours égal à totalReadBytesCount , donc le progress sera toujours 100.
  • vous avez probablement voulu utiliser ftpStream.Length , mais cela ne peut pas être lu.
  • essentiellement avec le protocole FTP, vous ne savez pas la taille du fichier que vous téléchargez. Si vous avez besoin de le connaître, vous devez l'interroger explicitement avant le téléchargement. Ici j'utilise le WebRequestMethods.Ftp.GetFileSize pour que.
2
répondu Martin Prikryl 2017-11-28 08:13:55

sans savoir exactement ce que fait votre code dans le ProgressChanged eventhandler, je pense que vous avez involontairement mis les parenthèses dans votre calcul de progression après * 100 .

Vous pouvez essayer ceci:

var progress = (int)((float)totalReadBytesCount / (float)fileStream.Length) * 100;
0
répondu Dick Appel 2017-07-23 20:09:00

j'ai maintenant une solution qui me convient.

L'Idée d'obtenir d'abord la Taille du Fichier est grande. Mais quand je fais une requête pour vérifier la taille du fichier, le serveur Ftp lance une erreur. Pareil FtpWebRequest erreur: 550 Taille pas autorisés en mode ASCII

maintenant, je téléchargez un fichier dummy pour ouvrir la connexion.. Voir ci-dessous

Merci à tous pour le Soutien.

grande Communauté. Grâce.

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


        }
0
répondu Andre 2017-07-24 15:03:58