https://stackoverflow.com/questions/4591059/download-file-from-ftp-with-progress-totalbytestoreceive-is-always-1

With FTP protocol, WebClient in general does not know total download size. So you commonly get -1 with FTP.

Note that the behavior actually contradicts the .NET documentation, which says for FtpWebResponse.ContentLength (where the value of TotalBytesToReceive comes from):

For requests that use the DownloadFile method, the property is greater than zero if the downloaded file contained data and is zero if it was empty.
But you will easily find out many of questions about this, effectively showing that the behavior is not always as documented. The FtpWebResponse.ContentLength has a meaningful value for GetFileSize method only.

The FtpWebRequest/WebClient makes no explicit attempt to find out a size of the file that it is downloading. All it does is that it tries to look for (xxx bytes). string in 125/150 responses to RETR command. No FTP RFC mandates that the server should include such information. ProFTPD (see data_pasv_open in src/data.c) and vsftpd (see handle_retr in postlogin.c) seem to include this information. Other common FTP servers (IIS, FileZilla) do not do this.

If your server does not provide size information, you have to query for size yourself before download. A complete solution using FtpWebRequest and Task:

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

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

C# show FTP Download/Upload progress的更多相关文章

  1. python ftp download with progressbar

    i am a new one to learn Python. Try to download by FTP. search basic code from baidu. no one tells h ...

  2. [Powershell] FTP Download File

    # Config $today = Get-Date -UFormat "%Y%m%d" $LogFilePath = "d:\ftpLog_$today.txt&quo ...

  3. FTP Download File By Some Order List

    @Echo Off REM -- Define File Filter, i.e. files with extension .RBSet FindStrArgs=/E /C:".asp&q ...

  4. PHP5.4新特性之上传进度支持Upload progress

    在PHP5.4版本当中给我们提供了好用的特性,上传进度的支持,我们可以配合Ajax动态获取SESSION当中的上传进度: 在使用这一特性之前,需要现在php.ini文件当中进行相应的设置:   1 2 ...

  5. PHP上传进度支持(Upload progress in sessions)

    文件上传进度反馈, 这个需求在当前是越来越普遍, 比如大附件邮件. 在PHP5.4以前, 我们可以通过APC提供的功能来实现. 或者使用PECL扩展uploadprogress来实现. 从PHP的角度 ...

  6. pycurl,Python cURL library

    pycurl — A Python interface to the cURL library Pycurl包是一个libcurl的Python接口.pycurl已经成功的在Python2.2到Pyt ...

  7. Pycurl介绍

    pycurl — A Python interface to the cURL library Pycurl包是一个libcurl的Python接口.pycurl已经成功的在Python2.2到Pyt ...

  8. Atitit s2018.5 s5 doc list on com pc.docx  v2

    Atitit s2018.5 s5  doc list on com pc.docx  Acc  112237553.docx Acc Acc  112237553.docx Acc baidu ne ...

  9. Atitit s2018.5 s5 doc list on com pc.docx  Acc 112237553.docx Acc baidu netdisk.docx Acc csdn 18821766710 attilax main num.docx Atiitt put post 工具 开发工具dev tool test.docx Atiitt 腾讯图像分类相册管家.docx

    Atitit s2018.5 s5  doc list on com pc.docx  Acc  112237553.docx Acc baidu netdisk.docx Acc csdn 1882 ...

随机推荐

  1. AJAX删除事件与加载数据

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. Jaguar_websocket结合Flutter搭建简单聊天室

    1.定义消息 在开始建立webSocket之前,我们需要定义消息,如:发送人,发送时间,发送人id等.. import 'dart:convert'; class ChatMessageData { ...

  3. Silverlight提示“Load 操作失败。远程服务器返回了错误: NotFound”

    调试时出现“Load 操作失败.远程服务器返回了错误: NotFound”: 一定要注意此错误之前的错误是什么?基本就是用户Cookie的问题,用户没有登录. 有时需要设置成Any CPU 有时重新编 ...

  4. Express使用Https服务器

    var fs = require('fs'); var http = require('http'); var https = require('https'); var privateKey = f ...

  5. eclipse代码中每行的开始和结尾出现多余的特殊符号

    window -> preferences -> general -> editors -> text editors ->          show whitespa ...

  6. 文档撰写思路与排版(hadoop)

    这几天在写项目提交的几个报告,写完回想了一下,在写作框架确定与排版上浪费了不少时间,特此总结一下思路. 这个写完回家过年了....emmmm 1. 定好大标题框架,使用自动添加序号,先不着急修改样式 ...

  7. Linux磁盘及分区之wwid和uuid

    背景描述,在Linux系统中,如果添加了新的SCSI磁盘或者映射SAN存储LUN操作,重启操作系统之后会出现磁盘标识符(sd*)错乱的情况. 例如之前添加的SAN存储LUN的磁盘标识符为/dev/sd ...

  8. Linux运维之——每日小技巧,谈进程与线程的区别

    线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源. ...

  9. C#中单问号(?)和双问号(??)的用法整理

    1.单问号(?) 1.1 表示Nullable类型 C#2.0里面实现了Nullable数据类型 //A.比如下面一句,直接定义int为null是错误的,错误提示为无法将null转化成int,因为后者 ...

  10. SDN负载均衡

    我负责的工作: (1).前期工作思路设计及方案选定.讲解 (2).后期代码修正 (3).视频制作 负载均衡程序 程序流程图 代码 from mininet.topo import Topo class ...