0

我在删除仅为发送带有附件的电子邮件然后在浏览器中查看而创建的文件时遇到问题。现在我需要删除这个文件,因为它只是为了发送电子邮件而创建的。我怎样才能做到这一点。

这是我到目前为止所得到的。

public void SendEmail()
 {
    EmailClient.Send(mailMessage);

    //View PDF Certificate in Browser
    ViewPDFinBrowser((string)fileObject);

    DeleteGeneratedTempCertificateFile((string)fileObject));
}    

public void ViewPDFinBrowser(string filePath)
  {
     PdfReader reader = new PdfReader(filePath);
     MemoryStream ms = new MemoryStream();

     PdfStamper stamper = new PdfStamper(reader, ms);
     stamper.ViewerPreferences = PdfWriter.PageLayoutSinglePage | PdfWriter.PageModeUseThumbs;
     stamper.Close();

     Response.Clear();
     Response.ContentType = "application/pdf";
     Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
     Response.OutputStream.Close();
     HttpContext.Current.ApplicationInstance.CompleteRequest();

  }

  public static void DeleteGeneratedTempCertificateFile(Object fileObject)
  {
      string filePath = (string)fileObject;
      if (File.Exists(filePath))
      {
          File.Delete(filePath);
      }
  }

所以这是我调用 SendEmail() 时需要的步骤

1) 发送带有附件的电子邮件 --> 创建临时文件 2) 在浏览器中查看临时文件 3) 删除临时文件

我可以理解,只要文件在响应对象中,我就不能对它做任何事情,因为我收到错误消息(“文件被另一个进程使用)。如果我关闭响应流,那么文件将被删除但我不能在浏览器中查看。

我在想,如果我能设法在单击按钮时以某种方式打开文件以在新窗口中的浏览器中查看,我将能够删除该文件。或者我想我可以在 10 分钟后删除文件。因为用户不会在现场查看 PDF 超过 1-2 分钟。

请用示例代码告诉我一种解决方案。

感谢您的时间和帮助。

4

1 回答 1

1

正如其他人所说,最好按原样使用 MemoryStream 而不将临时文件写入磁盘。有时 3rd 方组件的实现不允许这样做,在这种情况下,在编写 PDF 文件的二进制内容后,一定要调用 close (和/或可能处置,总是检查 MSDN 或 3rd 方 API 文档 .Close () 实际上确实如此)到所有不再需要的流。在您的情况下,在完成 http 请求后关闭msreader 。

在大多数情况下,考虑实现 using 模式。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/aa664736.aspx 。但是请记住,这种方法也有一些警告,例如在 WCF 客户端中,这可能会导致异常(因此实际上并未在 using 子句中处理所有内容)。

另外,请记住任何并发问题。保持临时文件名足够随机,并考虑文件已经存在于本地磁盘上的情况(即操作失败并且不向请求者不应该看到的请求发送二进制文件等)。

于 2012-08-03T11:03:24.207 回答