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";
var 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 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 tototalReadBytesCount
, hence theprogress
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.