Good afternoon, colleagues.

Please help with the correct display of the entire progress of downloading a folder from FTP. The code below allows you to download the entire directory. It works through backgroundworker, and you need help with displaying downloaded files.

Example: FTP 53 files (both in the root and in subfolders) require displaying the general download progress, that is 1 \ 53, 2 \ 53 and up to 100%. I hope it turned out to explain the code:

void DownloadFtpDirectory(string url, NetworkCredential credentials, string localPath) { FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url); listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; listRequest.Credentials = credentials; List<string> lines = new List<string>(); using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse()) using (Stream listStream = listResponse.GetResponseStream()) using (StreamReader listReader = new StreamReader(listStream)) { while (!listReader.EndOfStream) { lines.Add(listReader.ReadLine()); } } foreach (string line in lines) { string[] tokens = line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries); string name = tokens[8]; string permissions = tokens[0]; string localFilePath = Path.Combine(localPath, name); string fileUrl = url + name; if (permissions[0] == 'd') { if (!Directory.Exists(localFilePath)) { Directory.CreateDirectory(localFilePath); } DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath); } else { FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl); downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile; downloadRequest.Credentials = credentials; using (FtpWebResponse downloadResponse = (FtpWebResponse)downloadRequest.GetResponse()) using (Stream sourceStream = downloadResponse.GetResponseStream()) using (Stream targetStream = File.Create(localFilePath)) { byte[] buffer = new byte[2048]; int read; while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0) { targetStream.Write(buffer, 0, read); //Worker.ReportProgress("???????"); } } } } 
  • Count the number int countLines = lines.Count; and in the foreach (string line in lines) subtract one from countLines and output the result as progress. - Bulson
  • Yes, and the backgroundground is outdated crap. Read about TPL, IProgress and SynchronizationContext . - Bulson
  • If you display the downloaded bytes, then double progress is better. The first shows the progress of the current file, and the second shows the number of files. Of course it is better to know the total weight, but even with a linear progress much more clearly single. - vitidev

1 answer 1

I would advise you to first pull out the total weight of all the files and focus on it (.Maximum = this weight ;, and in the valyu enter the weight already downloaded). Whatever the situation is, the ftp will have 100 files of 100 kilobytes and 1 file per 1 gigabyte. And the last file in the progress bar will be shown as an equal part of the general information.

Just agree with Bulson. It is better to look towards TPL.

  • Andrew, thanks for the practical advice, but, unfortunately, the method that I found, calculates the directory for a long time. If you move you on the right path, I will be grateful. And about TPL, I read what kind of animal it is, but I spend all the frauds on net 3.5, and if I'm not mistaken, it is not supported (or not fully) - Asphy