【问题标题】:File Stream not return after closing it in finally block C#文件流在finally块C#中关闭后不返回
【发布时间】:2014-11-14 10:14:29
【问题描述】:

我通过使用 WCF 休息服务以如下流的形式返回来下载文件。

 Stream stream = null;          
            var directoryInformation = CommonServices.Utility.DirectoryHelper.GetTempFolderRootLocation();
            string newFolderPath = directoryInformation + "\\Attachments\\" + Guid.NewGuid();
            try
            {

                Directory.CreateDirectory(newFolderPath);
                DataSet getDocumentContent = GetDocumentContent(engagementId, documentId);
                var fileName = getDocumentContent.Tables[0].Rows[0]["Fullname"] as string;
                var byteData= getDocumentContent.Tables[0].Rows[0]["FilestreamContent"] as byte[];
                string fullPath = newFolderPath + "\\" + fileName;        
                using (var fileStream = new FileStream(fullPath, FileMode.Create))
                {
                    if (byteData != null)
                    {
                        fileStream.Write(byteData,0,byteData.Length);
                        fileStream.Close();
                    }

                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
                        WebOperationContext.Current.OutgoingResponse.Headers.Add("content-disposition","inline; filename=" + fileName);
                    }
                }
                stream = File.OpenRead(fullPath);
                return stream;
            }
            catch (Exception exception)
            {

                return null;
            }

以上代码完美运行,可以在浏览器中下载文件。但是我必须在返回流后删除文件。所以我尝试关闭并删除包含 finally 块中的目录的文件,如下所示

   finally
            {
                if (stream != null) stream.Close();
                Directory.Delete(newFolderPath, true);
            } 

完整的方法代码

 public Stream DownloadAttachment(string engagementId, string documentId)
        {
            Stream stream = null;          
            var directoryInformation = CommonServices.Utility.DirectoryHelper.GetTempFolderRootLocation();
            string newFolderPath = directoryInformation + "\\Attachments\\" + Guid.NewGuid();
            try
            {

                Directory.CreateDirectory(newFolderPath);
                DataSet getDocumentContent = GetDocumentContent(engagementId, documentId);
                var fileName = getDocumentContent.Tables[0].Rows[0]["Fullname"] as string;
                var byteData= getDocumentContent.Tables[0].Rows[0]["FilestreamContent"] as byte[];
                string fullPath = newFolderPath + "\\" + fileName;        
                using (var fileStream = new FileStream(fullPath, FileMode.Create))
                {
                    if (byteData != null)
                    {
                        fileStream.Write(byteData,0,byteData.Length);
                        fileStream.Close();
                    }

                    if (WebOperationContext.Current != null)
                    {
                        WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
                        WebOperationContext.Current.OutgoingResponse.Headers.Add("content-disposition","inline; filename=" + fileName);
                    }
                }
                stream = File.OpenRead(fullPath);
                return stream;
            }
            catch (Exception exception)
            {

                return null;
            }
           finally
            {
                if (stream != null) stream.Close();
                Directory.Delete(newFolderPath, true);
            }
        }

添加后这个代码文件在客户端没有下载。有什么办法可以删除这个文件吗?请帮我解决这个问题

【问题讨论】:

  • 您是否在上述方法的末尾添加了这个 finally 块?如果是这样,Close 将处理您尝试返回的同一流。
  • 能否请您看一下源代码。我已通过添加完整方法更新了我的问题
  • 您正在尝试将 fileStream 返回到已删除的文件?
  • 实际上我从服务器读取文件后有返回流,因此浏览器将根据内容类型下载此文件。但是在返回流之后,我必须删除该文件。当我尝试在不关闭的情况下删除此文件时,它显示另一个进程正在使用异常文件
  • 您不能将FileStream 返回到要删除的文件,因为FileStream 将持有该文件的句柄。为什么不使用文件返回一个 byte[] 呢?

标签: c# .net wcf rest


【解决方案1】:

您可以删除OperationContext.OperationCompleted中的文件,如http://devdump.wordpress.com/2008/12/07/disposing-return-values/所示

OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted += new EventHandler(delegate(object sender, EventArgs args)
   {
          if (stream != null) stream.Close();
          Directory.Delete(newFolderPath, true);
   });

【讨论】:

    【解决方案2】:

    把你的方法改成这个。

    public void DownloadAttachment(string engagementId, string documentId, Action<Stream> processFile)
    

    而不是返回流调用 processFile Action

    processFile(stream);
    

    这样您就不会为了处理文件而离开方法。不过,您需要重新构造调用代码才能处理该文件。

    【讨论】:

      猜你喜欢
      • 2012-02-17
      • 2017-07-20
      • 1970-01-01
      • 2010-09-08
      • 2014-04-27
      • 2022-01-14
      相关资源
      最近更新 更多