2011-01-04 36 views
6

プログレスバーを使用してFTPサーバーからファイルをダウンロードしようとしています。ProgressでFTPからファイルをダウンロード - TotalBytesToReceiveは常に-1ですか?

ファイルがダウンロードされていて、ProgressChangedイベントが呼び出されています(ただし、イベント引数TotalBytesToReceiveは常に-1です)。 TotalBytesは増加しますが、合計なしでパーセンテージを計算することはできません。

私は他のftpコマンドでファイルサイズを見つけることができたと思いますが、なぜこれが機能しないのでしょうか?

マイコード:

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; 
    } 
} 

感謝。

+0

あなたがより良い実装を提供する必要がありますようですそれを処理する 'WebClient'興味深いプロパティ/メソッドを探して上書きする。 – leppie

+0

'WebClient'を見ましたが、多くのハッキングなしで実装することはほとんど不可能です。 – leppie

答えて

-1

FTP HTTPのようなコンテンツサイズを与えることはできませんが、あなた自身でこれを行う方がよいでしょう。

FtpWebRequest FTPWbReq = WebRequest.Create("somefile") as FtpWebRequest; 
FTPWbReq .Method = WebRequestMethods.Ftp.GetFileSize; 

FtpWebResponse FTPWebRes = FTPWbReq.GetResponse() as FtpWebResponse; 
long length = FTPWebRes.ContentLength; 
FTPWebRes.Close(); 
4

私は同じ問題がありました。私は最初にファイルサイズを取得して周りにいた。

 // 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")); 

次に、コールバックで数式を実行します。 FtpWebRequestTaskを使用して

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

ソリューション:

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

コアのダウンロードコードが基づいている:
Upload and download a binary file to/from FTP server in C#/.NET

関連する問題