FtpWebRequest 使用 ProgressBar 进行 FTP 下载

时间:2023-03-30
本文介绍了FtpWebRequest 使用 ProgressBar 进行 FTP 下载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我的代码可以运行,但是 ProgressBar 直接跳转到 100% 并且继续下载.完成后会出现一个消息框来获取信息.

My code works, but the ProgressBar jumps directly to 100% and the download will go on. When its finished then comes a messageBox to take a Info.

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

I have already changed the buffer size, but it doesn't matter.

我在这里做错了什么?

这是我的代码:

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

推荐答案

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

Trivial example of FTP download using FtpWebRequest with WinForms progress bar:

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:localpathfile.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);
    }
}

核心下载代码基于:
在 C#/.NET 中向/从 FTP 服务器上传和下载二进制文件

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

To explain why your code does not work:

  • 您正在使用目标文件的大小进行计算:fileStream.Length – 它始终等于 totalReadBytesCount,因此是 progress 永远是 100.
  • 您可能打算使用 ftpStream.Length,但无法读取.
  • 基本上使用 FTP 协议,您不知道正在下载的文件的大小.如果你需要知道它,你必须在下载之前明确地查询它.在这里,我使用 WebRequestMethods.Ftp.GetFileSize.
  • You are using size of the target file for the calculation: fileStream.Length – It will always be equal to totalReadBytesCount, hence the progress will always be 100.
  • You probably meant to use ftpStream.Length, but that cannot be read.
  • Basically with FTP protocol, you do not know size of the file you are downloading. If you need to know it, you have to query it explicitly before the download. Here I use the WebRequestMethods.Ftp.GetFileSize for that.

这篇关于FtpWebRequest 使用 ProgressBar 进行 FTP 下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:如何使用 C# 在 FTP 服务器上创建目录? 下一篇:带有通配符的 FTP 目录部分列表

相关文章