Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
504 views
in Technique[技术] by (71.8m points)

c# - Download file from FTP with Progress - TotalBytesToReceive is always -1?

I am trying to download a file from an FTP server with a progress bar.

The file is downloading, and the ProgressChanged event is calling, except in the event args TotalBytesToReceive is always -1. TotalBytes increases, but I am unable to calculate the percentage without the total.

I imagine I could find the file size through other ftp commands, but I wonder why this doesn't work?

My code:

FTPClient request = new FTPClient();
request.Credentials = credentials;
request.DownloadProgressChanged += new DownloadProgressChangedEventHandler(request_DownloadProgressChanged);
//request.DownloadDataCompleted += new DownloadDataCompletedEventHandler(request_DownloadDataCompleted);
request.DownloadDataAsync(new Uri(folder + file));
while (request.IsBusy) ;

....

static void request_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    if (e.TotalBytesToReceive == -1)
    {
        l.reportProgress(-1, FormatBytes(e.BytesReceived) + " out of ?" );
    }
    else
    {
        l.reportProgress(e.ProgressPercentage, "Downloaded " + FormatBytes(e.BytesReceived) + " out of " + FormatBytes(e.TotalBytesToReceive) + " (" + e.ProgressPercentage + "%)");
    }
}

....

class FTPClient : WebClient
{
    protected override WebRequest GetWebRequest(System.Uri address)
    {
        FtpWebRequest req = (FtpWebRequest)base.GetWebRequest(address);
        req.UsePassive = false;
        return req;
    }
}

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

So I had the same issue. I got around it by retrieving the file size first.

        // Get the object used to communicate with the server.
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create("URL");
        request.Method = WebRequestMethods.Ftp.GetFileSize;
        request.Credentials = networkCredential;
        FtpWebResponse response = (FtpWebResponse)request.GetResponse();

        Stream responseStream = response.GetResponseStream();
        bytes_total = response.ContentLength; //this is an int member variable stored for later
        Console.WriteLine("Fetch Complete, ContentLength {0}", response.ContentLength);
        response.Close();

        webClient = new MyWebClient();
        webClient.Credentials = networkCredential; ;
        webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(FTPDownloadCompleted);
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FTPDownloadProgressChanged);
        webClient.DownloadDataAsync(new Uri("URL"));

Then do the math in the callback.

private void FTPDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
     progressBar.Value = (int)(((float)e.BytesReceived / (float)bytes_total) * 100.0);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...