FtpWebRequest FTP与ProgressBar下载 [英] FtpWebRequest FTP download with ProgressBar

查看:111
本文介绍了FtpWebRequest FTP与ProgressBar下载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码可以正常工作,但是 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); $(b)b
label4.Invoke((MethodInvoker)delegate {label4.Text =Downloading File ..;});

string ftpServerIP =XXX;
string ftpUserName =XXX;
字符串ftpPassword =XXX;

尝试
{
//发送FTP服务器下载
FtpWebRequest请求=(FtpWebRequest)WebRequest.Create(ftp://+ ftpServerIP +/ + fileName);
request.Credentials = new NetworkCredential(ftpUserName,ftpPassword);
request.Method = WebRequestMethods.Ftp.DownloadFile;
using(Stream stream ftpStream = request.GetResponse()。GetResponseStream())
using(Stream fileStream = File.Create(fileFullPath))
{
var buffer = new byte [ 32 * 1024];
int totalReadBytesCount = 0;
int readBytesCount; ((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); $(b)b label3.Invoke((MethodInvoker)delegate {label3.Text = progress +%;});


$ b catch(WebException例外)
{
FtpWebResponse响应=(FtpWebResponse)ex.Response;

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


$ b void workerDOWN_RunWorkerCompleted(对象发件人,RunWorkerCompletedEventArgs e)
{
字符串fileFullPath = e.Result as String;
string fileName = Path.GetFileName(fileFullPath);

MessageBox.Show(下载erfolgreich!,信息);

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


解决方案

FtpWebRequest with WinForms progress bar:

  private void button1_Click(object sender, EventArgs e)
{
//在后台线程上运行下载
Task.Run(()=>下载());


private void Download()
{
try
{
const string url =ftp://ftp.example。 COM /远程/路径/ file.zip;
NetworkCredential凭证=新的NetworkCredential(用户名,密码);

//待下载文件的查询大小
WebRequest sizeRequest = WebRequest.Create(url);
sizeRequest.Credentials =凭证;
sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;
int size =(int)sizeRequest.GetResponse()。ContentLength;

progressBar1.Invoke(
(MethodInvoker)(()=> progressBar1.Maximum = size));

//下载文件
WebRequest请求= WebRequest.Create(url);
request.Credentials = credentials;
request.Method = WebRequestMethods.Ftp.DownloadFile;使用(Stream fileStream = File.Create(@C:\ local \\\\\\\\\\\' zip))
{
byte [] buffer = new byte [10240];
int读取; ((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);
}
}






解释为什么您的代码无效:


  • 您正在使用目标文件的大小进行计算: fileStream.Length - 它总是等于 totalReadBytesCount ,因此 progress 将始终为100.

  • 您可能打算使用 ftpStream.Length ,但无法读取。

  • 基本上使用FTP协议,您不知道要下载的文件的大小。如果你需要知道它,你必须在下载之前明确地查询它。在这里我使用了 WebRequestMethods.Ftp.GetFileSize


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.

What am I doing wrong here?

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

解决方案

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

The core download code is based on:
Upload and download a binary file to/from FTP server in C#/.NET


To explain why your code does not work:

  • 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 FTP与ProgressBar下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆