2011-09-23 114 views
1

我正在創建一個ftp實用程序,它將保存用戶的進度,並重新上傳給定文件,如果他們的互聯網斷開連接,他們將從其中啓動。 (這適用於連接速度較慢的客戶端)。FtpWebRequest.GetRequestStream()斷開連接後

這個想法是打開一個文件流和ftp流,並以大塊內存寫入到ftp流。如果異常升高(即斷開IOException),則寫入ftp服務器的字節數將保存在日誌文件中並在啓動時讀取。如果交易被取消

此代碼的工作很大,但如果客戶端斷開連接,然後FTP流從不清理在服務器端 - 所以我接受...

遠程服務器返回的錯誤:(550)文件不可用(例如,文件未找到,無法訪問)。

當重新請求給定文件的ftp流時。代碼看起來像

 //Create FTP Web Request 
    reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(builder.ToString())); 
    reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 
    reqFTP.Method = WebRequestMethods.Ftp.UploadFile; 
    reqFTP.UsePassive = true; 
    reqFTP.UseBinary = false; 
    reqFTP.KeepAlive = false; 
    reqFTP.ContentLength = fileInf.Length; 
    reqFTP.ReadWriteTimeout = 5000; 
    reqFTP.Timeout = 5000; 

    using (ProgressDialog progressDialog = new ProgressDialog()) 
    { 
     progressDialog.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork); 
     progressDialog.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted); 
     progressDialog.backgroundWorker1.FileName = filename; 
     progressDialog.ShowDialog(); 
    } 
    } 

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
    FTPBackgroundWorker worker = sender as FTPBackgroundWorker; 

    //Get file progress (if user canceled or crashed) 
    worker.NumBytesRead = GetFileProgress(worker.FileName); 
    reqFTP.ContentOffset = worker.NumBytesRead; 

    const int buffLength = 2048; 
    byte[] buff = new byte[buffLength]; 
    int contentLen; 

    using (worker.FileStream = fileInf.OpenRead()) 
    { 
     worker.FileStream.Position = worker.NumBytesRead; 
     worker.FTPStream = reqFTP.GetRequestStream(); //Exception occurs 

     while (true) 
     { 
      bool throwException = false; 
      if (worker.CancellationPending) 
      { 
       e.Cancel = true; 
       break; 
      } 

      contentLen = worker.FileStream.Read(buff, 0, buffLength); 
      if (contentLen == 0) 
       break; 

      //write file to ftp stream 
      worker.FTPStream.Write(buff, 0, contentLen); 
      worker.NumBytesRead += contentLen; 

      //For testing purposes 
      if (throwException) 
       throw new Exception("user disconnected!"); 
      worker.ReportProgress((int)(((double)worker.NumBytesRead/fileInf.Length) * 100)); 
     } 
     worker.FileStream.Close(); 
     worker.FTPStream.Close(); 
    } 
    } 

    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
    FTPBackgroundWorker worker = sender as FTPBackgroundWorker; 
    if (e.Error != null) 
    { 
     MessageBox.Show(String.Format("Error occured uploading {0}: {1}",worker.FileName, e.Error), "Error"); 
     if (worker.FileStream != null) 
      worker.FileStream.Close(); 
     if (worker.FTPStream != null) 
      worker.FTPStream.Close(); 

     if(worker.NumBytesRead > 0) 
     { 
      MessageBox.Show("Progress has been saved", "Notification"); 
      WriteToLogFile(worker.FileName, worker.NumBytesRead); 
     } 
    } 
    else if (e.Cancelled) 
    { 
     if (worker.FileStream != null) 
      worker.FileStream.Close(); 
     if (worker.FTPStream != null) 
      worker.FTPStream.Close(); 

     MessageBox.Show("Upload Canceled", "Cancel"); 
     if (worker.NumBytesRead > 0 && MessageBox.Show("Would you like to save your upload progress?", "Notification", MessageBoxButtons.YesNo) == DialogResult.Yes) 
      WriteToLogFile(worker.FileName, worker.NumBytesRead); 
    } 
    else 
    { 
     RemoveFromLogFile(worker.FileName); 
     MessageBox.Show("Upload Complete", "Success"); 
    } 
    } 

我的問題是:有沒有一種方法來檢查是否有對其他沒有讓一個文件的路徑走,並刪除它的服務器端的手柄?或者我用錯誤的方法來解決問題?

感謝

+0

你好,請問如何在ftp類上傳或下載的時候實現進度 – Smith

+0

嗨,這跟跟蹤寫入FTPStream的字節數一樣簡單。我只是將它存儲在一個日誌中供我實現。 worker.FTPStream.Write(buff,0,contentLen); worker.NumBytesRead + = contentLen; – mthelen

+0

謝謝,如果我需要做同樣的上傳,會發生什麼變化? – Smith

回答

0

爲什麼不遞減超時的連接試圖重新初始化或者讓用戶等待嘗試再次啓動連接之前,將到期的值?

+0

我認爲這可能是最好的(也是唯一的)解決方案 – mthelen