私は、ユーザーの進捗状況を保存するftpユーティリティのプロトタイプを作成しており、インターネットが切断された場合に開始した場所からファイルを再アップロードします。 (接続が遅いクライアント向けです)。FtpWebRequest.GetRequestStream()disconnect after after
アイデアは、ファイルストリームと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");
}
}
のように見える私の質問は:ファイルパスを手放すていないサーバー側のハンドルがありますかどうかを確認し、それを削除する方法はありますか?あるいは、間違った方法で問題に近づいていますか?
おかげ
こんにちは、ftpクラスでアップロードまたはダウンロード中に進捗状況をどのように実装するか尋ねることができます。 – Smith
こんにちは、FTPStreamに書き込まれたバイト数を記録するのと同じくらい簡単です。私は実装のためにログに保存しました。 worker.FTPStream.Write(buff、0、contentLen); worker.NumBytesRead + = contentLen; – mthelen
ありがとう、私はアップロードのために同じことをする必要があった場合、何か変更はありますか? – Smith