使用ProgressBar进行FtpWebRequest FTP下载

时间:2017-07-23 19:46:39

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

我的代码有效,但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 = " "; });      
}

3 个答案:

答案 0 :(得分:2)

使用带有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);
    }
}

enter image description here

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

解释您的代码无效的原因:

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

答案 1 :(得分:0)

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

你可以试试这个:

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

答案 2 :(得分:0)

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

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

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

感谢大家的支持。

伟大的社区。感谢。

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


        }