2011-06-14 96 views
23

我使用FtpWebRequest將文件上傳到ftp。我需要顯示已完成多少工作的狀態。如何使用FtpWebRequest顯示上傳進度條

到目前爲止,我的代碼是:

public void Upload(string filename, string url) 
{ 
    FileInfo fileInf = new FileInfo(filename); 
    string uri = "ftp://" + url + "/" + fileInf.Name; 
    FtpWebRequest reqFTP; 
    //string uri = "ftp://" + Host + "/public_html/testing/blogtest/" + fileInf.Name; 

    // Create FtpWebRequest object from the Uri provided 
    reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 

    // Provide the WebPermission Credintials 
    reqFTP.Credentials = new NetworkCredential(Username, Password); 

    // By default KeepAlive is true, where the control connection is not closed 
    // after a command is executed. 
    reqFTP.KeepAlive = false; 
    //reqFTP.UsePassive = true; 
    // Specify the command to be executed. 
    reqFTP.Method = WebRequestMethods.Ftp.UploadFile; 

    // Specify the data transfer type. 
    reqFTP.UseBinary = true; 

    // Notify the server about the size of the uploaded file 
    reqFTP.ContentLength = fileInf.Length; 

    // The buffer size is set to 2kb 
    int buffLength = 2048; 
    byte[] buff = new byte[buffLength]; 
    int contentLen; 

    // Opens a file stream (System.IO.FileStream) to read the file to be uploaded 
    FileStream fs = fileInf.OpenRead(); 

    // Stream to which the file to be upload is written 
    Stream strm = reqFTP.GetRequestStream(); 

    // Read from the file stream 2kb at a time 
    contentLen = fs.Read(buff, 0, buffLength); 

    // Till Stream content ends 
    while (contentLen != 0) 
    { 
     // Write Content from the file stream to the FTP Upload Stream 
     strm.Write(buff, 0, contentLen); 
     contentLen = fs.Read(buff, 0, buffLength); 
    } 

    // Close the file stream and the Request Stream 
    strm.Close(); 
    fs.Close(); 
} 

回答

35

最簡單的方法是使用BackgroundWorker,把你的代碼放到DoWork事件處理程序。並用BackgroundWorker.ReportProgress報告進度。

的基本思想:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    var ftpWebRequest = (FtpWebRequest)WebRequest.Create("ftp://example.com"); 
    ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile; 
    using (var inputStream = File.OpenRead(fileName)) 
    using (var outputStream = ftpWebRequest.GetRequestStream()) 
    { 
     var buffer = new byte[1024 * 1024]; 
     int totalReadBytesCount = 0; 
     int readBytesCount; 
     while ((readBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      outputStream.Write(buffer, 0, readBytesCount); 
      totalReadBytesCount += readBytesCount; 
      var progress = totalReadBytesCount * 100.0/inputStream.Length; 
      backgroundWorker1.ReportProgress((int)progress); 
     } 
    } 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar.Value = e.ProgressPercentage; 
} 

確保WorkerReportsProgress啓用

backgroundWorker2.WorkerReportsProgress = true; 

隨着BackgroundWorker你也可以輕鬆實現上傳取消。

+0

是的,但是分辨率並不好洙3MB上傳文件顯示,只有23%的53,然後100 – 2011-06-14 11:54:26

+2

@Afnan巴希爾 - 你可以調整緩存大小您的需求。 – 2011-06-14 15:23:21

+0

太棒了!但是不應該關閉'inputStream'和'outputStream'嗎? – ocramot 2015-05-18 12:39:20

0

請參閱BackgroundWorker,它允許您運行耗時的任務,同時GUI仍然響應並且還提供進度/取消。

+3

這是一個僅限於邊界的鏈接答案。你應該擴大你的答案,在這裏包含儘可能多的信息,並使用鏈接僅供參考。 – gunr2171 2014-12-10 20:06:06

1

使用Task class使用FtpWebRequest與WinForms的進度條FTP上傳的簡單的例子:

private void button1_Click(object sender, EventArgs e) 
{ 
    // Run Upload on background thread 
    Task.Run(() => Upload()); 
} 

private void Upload() 
{ 
    FtpWebRequest request = 
     (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip"); 
    request.Credentials = new NetworkCredential("username", "password"); 
    request.Method = WebRequestMethods.Ftp.UploadFile; 

    using (Stream fileStream = File.OpenRead(@"C:\local\path\file.zip")) 
    using (Stream ftpStream = request.GetRequestStream()) 
    { 
     progressBar1.Invoke(
      (MethodInvoker)delegate { progressBar1.Maximum = (int)fileStream.Length; }); 

     byte[] buffer = new byte[10240]; 
     int read; 
     while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      ftpStream.Write(buffer, 0, read); 
      progressBar1.Invoke(
       (MethodInvoker)delegate { 
        progressBar1.Value = (int)fileStream.Position; }); 
     } 
    } 
} 

enter image description here

芯上載的代碼是基於:
Upload and download a binary file to/from FTP server in C#/.NET

0
使用

可取消的方法異步/等待模式的IProgress接口,利用overlapped I/O(如果可用)。請參閱KB156932以確定您的方案是否合格。在打開流之前檢查取消標記,但在文件傳輸過程中否則會被卸載到流的異步方法。

我已經做了很少的基準測試,但懷疑這隻在發送大文件時才實用。使用重疊I/O的性能可能會隨着較小的文件,特別是較小的緩衝區大小而降低。

public async Task FtpAsync(string sourceFile, Uri destinationUri, string user, SecureString password, IProgress<decimal> progress, CancellationToken token) 
{ 
    const int bufferSize = 128 * 1024; // 128kb buffer 
    progress.Report(0m); 

    var request = (FtpWebRequest)WebRequest.Create(destinationUri); 
    request.Method = WebRequestMethods.Ftp.UploadFile; 
    request.Credentials = new NetworkCredential(user, password); 

    token.ThrowIfCancellationRequested(); 

    using (var fileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, true)) 
    { 
    using (var ftpStream = await request.GetRequestStreamAsync()) 
    { 
     var buffer = new byte[bufferSize]; 
     int read; 

     while ((read = await fileStream.ReadAsync(buffer, 0, buffer.Length, token)) > 0) 
     { 
     await ftpStream.WriteAsync(buffer, 0, read, token); 
     var percent = 100m * ((decimal)fileStream.Position/fileStream.Length); 
     progress.Report(percent); 
     } 
    } 
    } 

    var response = (FtpWebResponse)await request.GetResponseAsync(); 
    var success = (int)response.StatusCode >= 200 && (int)response.StatusCode < 300; 
    response.Close(); 
    if (!success) 
    throw new Exception(response.StatusDescription); 
}