2009-04-24 27 views
5

リモートサービスプロバイダから〜40MBのCSVファイルをFTPするには、次のC#コードを使用しています。約50%の時間で、ダウンロードが中断し、最終的にタイムアウトします。私はLeechFTPのようなグラフィカルなクライアントを使用して対話形式でファイルをダウンロードすると、ダウンロードがハングアップしないと、約45秒で完全にほとんどないC#アプリケーションでFTPタイムアウトを解決する方法

> Unable to read data from the transport 
> connection: A connection attempt 
> failed because the connected party did 
> not properly respond after a period of 
> time, or established connection failed 
> because connected host has failed to 
> respond. 

:私のアプリのログでは、私のような行を取得します。私は間違っていることを理解する時間を持っています。

このコードをどのように計測して、何が起こっているのか、このファイルをダウンロードするためのより良い方法を知ることができますか?私はバッファサイズを増やすべきですか?どれくらい?ディスクへのバッファリングされた書き込みを避け、メモリ内のファイル全体を呑み込もうとしますか?どんなアドバイスもありがとう!

... 

private void CreateDownloadFile() 
    { 
     _OutputFile = new FileStream(_SourceFile, FileMode.Create); 
    } 
public string FTPDownloadFile() 
    { 
     this.CreateDownloadFile(); 

     myReq = (FtpWebRequest)FtpWebRequest.Create(new Uri(this.DownloadURI)); 
     myReq.Method = WebRequestMethods.Ftp.DownloadFile; 
     myReq.UseBinary = true; 
     myReq.Credentials = new NetworkCredential(_ID, _Password); 

     FtpWebResponse myResp = (FtpWebResponse)myReq.GetResponse(); 
     Stream ftpStream = myResp.GetResponseStream(); 

     int bufferSize = 2048; 
     int readCount; 
     byte[] buffer = new byte[bufferSize]; 
     int bytesRead = 0; 
     readCount = ftpStream.Read(buffer, 0, bufferSize); 

     while (readCount > 0) 
     { 
      _OutputFile.Write(buffer, 0, readCount); 
      readCount = ftpStream.Read(buffer, 0, bufferSize); 

      Console.Write('.'); // show progress on the console 
      bytesRead += readCount; 
     } 
     Console.WriteLine(); 
     logger.logActivity(" FTP received " + String.Format("{0:0,0}", bytesRead) + " bytes"); 

     ftpStream.Close(); 
     _OutputFile.Close(); 
     myResp.Close(); 
     return this.GetFTPStatus(); 
    } 

    public string GetFTPStatus() 
    { 
     return ((FtpWebResponse)myReq.GetResponse()).StatusDescription; 
    } 

答えて

0

私はコードレベルでFTPを処理していませんが、FTPは再開をサポートしています。タイムアウト時に自動的にアップロードを再開しようとする可能性があります

+0

うん、良いアイデア - それは根本的な問題を解決するのではなく、むしろ働きます。グラフィカルなFTPクライアントはめったにタイムアウトしません。なぜ私のコードはそうするのですか? –

1

FTPアクセスにFtpWebRequestを使用しないことをお勧めします。 FtpWebRequestは私が見た中で最も脳が枯渇したFTP APIです。

現在、私はまた、私は上記の提案としてFTPClientを使用しようと同じタイムアウトエラーを得たIndySockets http://www.indyproject.org/index.en.aspx

+0

はい、FTPWebRequest APIの評価には間違いありません。私はこのコードを継承し、大きな変更を加えたくはありませんでした。クラス名に「Web」があるという事実だけが手掛かりです.FTPにはWebとは関係がありません!あなたが参照する図書館を見ていきます。ありがとう! –

+2

面白いことに、CodePlexのFtpClientはFTPWebRequest APIを使用しています。拡張は不要です。むしろSocketクラスを見てください。 – SollyM

2

と幸運を持っていたFtpClient http://www.codeplex.com/ftpclient

を使用し、FTPClientので、私は何かが欠けする必要がありますたFtpWebRequestを使用しています私はその点を見ない。私はそれを発見したいくつかのより多くの研究-1後

が、私がそれと一緒に行ったように、無限大を使用しても大丈夫です、私の目的のために無限

ための値であり、問​​題は解決しました。ここで

は私のコードです:

//は、FTPサイトからファイルを取得します。

 FtpWebRequest reqFTP; 

     string fileName = @"c:\downloadDir\localFileName.txt"; 
     FileInfo downloadFile = new FileInfo(fileName); 
     string uri = "ftp://ftp.myftpsite.com/ftpDir/remoteFileName.txt"; 


     FileStream outputStream = new FileStream(fileName, FileMode.Append); 

     reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri)); 
     reqFTP.Method = WebRequestMethods.Ftp.DownloadFile; 
     reqFTP.UseBinary = true; 
     reqFTP.KeepAlive = false; 
     reqFTP.Timeout = -1; 
     reqFTP.UsePassive = true; 
     reqFTP.Credentials = new NetworkCredential("userName", "passWord"); 
     FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 
     Stream ftpStream = response.GetResponseStream(); 
     long cl = response.ContentLength; 
     int bufferSize = 2048; 
     int readCount; 
     byte[] buffer = new byte[bufferSize]; 
     readCount = ftpStream.Read(buffer, 0, bufferSize); 
     Console.WriteLine("Connected: Downloading File"); 
     while (readCount > 0) 
     { 
      outputStream.Write(buffer, 0, readCount); 
      readCount = ftpStream.Read(buffer, 0, bufferSize); 
      Console.WriteLine(readCount.ToString()); 
     } 

     ftpStream.Close(); 
     outputStream.Close(); 
     response.Close(); 
     Console.WriteLine("Downloading Complete"); 
関連する問題