在C#中关闭ftp流时出错

时间:2009-03-26 14:15:06

标签: c# ftp

我正在尝试取消下载操作。我的方案如下:

当用户点击取消下载按钮时,此操作会在下载功能中抛出异常,如下所示:

        try
        {
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + uri + "/" + fileName));
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
            reqFTP.UseBinary = true;
            reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
            reqFTP.UsePassive = true;

            response = (FtpWebResponse)reqFTP.GetResponse();
            ftpStream = response.GetResponseStream();
            _isItOutputStream = true;
            string dataLengthString = response.Headers["Content-Length"];
            int dataLength = 0;
            if (dataLengthString != null)
            {
                dataLength = Convert.ToInt32(dataLengthString);
            }

            long cl = response.ContentLength;
            int bufferSize = 4048;
            int readCount;
            byte[] buffer = new byte[bufferSize];
            readCount = ftpStream.Read(buffer, 0, bufferSize);
            outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);
            bool first = true;
            while (readCount > 0)
            {
                outputStream.Write(buffer, 0, readCount);
                _actualDownloaded += readCount;
                if (this.InvokeRequired)
                {
                    ProgressBarDel _progressDel = new ProgressBarDel(ProgressBar);
                    this.Invoke(_progressDel, new object[] { _actualDownloaded, first });
                }
                first = false;
                readCount = ftpStream.Read(buffer, 0, bufferSize);
            }
            ftpStream.Close();
            outputStream.Close();
            response.Close();
            _isItOutputStream = false;
            return true;
        }
        catch (Exception ee)
        {
            _downloadException = ee.Message;
            if (response != null)
            {

                outputStream.Close();
                ftpStream.Close();
                response.Close();
            }
            return false;
        }

在这里引发异常的行“ftpStream.Close()”中......

例外文字是:

  

远程服务器返回错误:   (450)文件不可用(例如,文件   忙)

它打开一个要下载的文件,因为我写的是“outputStream = new FileStream(filePath + "\\" + fileName, FileMode.Create);”我不会关闭此流并按顺序关闭响应,如果用户执行如下操作: 下载 - >取消下载 - >下载 - >取消下载 - >下载

如果发生这种情况,应用程序就会挂起。我不知道如何关闭流和响应,所以我可以停止下载然后删除创建的文件,以便再次下载。

日Thnx

2 个答案:

答案 0 :(得分:3)

似乎导致您执行的行是下面的行,这是由于FTP服务器找不到您想要的文件。这种情况可能很容易再次发生,因此可能值得在该单独的行周围放置一个try / catch块,或者使用它正在生成的特定异常的catch。

ftpStream = response.GetResponseStream();

在catch块中,您正在使用outputStream.Close(),但如果上面的行发生异常,则outputStream将为null。至少你应该改变在catch块中关闭对象的顺序,并检查它们是否为null。

if(response != null) {
    response.Close();
}

if(ftpStream != null) {
    ftpStream.Close();
}

if(outputStream != null) {
    outputStream.Close();
}

答案 1 :(得分:1)

首先关闭,将你的关闭放在finally块中。

因此,请确保您的代码是这样的,以确保无论如何都会关闭流。

try
{
   //Your existing logic
   //Don't need to close the streams/etc
}
catch
{
   //Just do what you need to with the exception
}
finally
{
   //This is always called
   if (response != null)
      response.Close();
   if(outputStream != null)
      outputStream.Close();
   if(ftpStream != null)
      ftpStream.Close();
} 

在try catch

中包装此行
ftpStream = response.GetResponseStream();

只要调用那些Close调用,你的取消逻辑在哪​​里就可以了?我希望在用户单击按钮时设置循环上的标志。 e.g。

while (readCount > 0 && !_shouldExit)
{
   outputStream.Write(buffer, 0, readCount);
  _actualDownloaded += readCount;
  if (this.InvokeRequired)
  {
    ProgressBarDel _progressDel = new ProgressBarDel(ProgressBar);
    this.Invoke(_progressDel, new object[] { _actualDownloaded, first });
  }
  first = false;
  readCount = ftpStream.Read(buffer, 0, bufferSize);
}