在向用户显示后立即删除动态生成的PDF文件

时间:2009-03-18 09:50:00

标签: c# asp.net vb.net pdf-generation

我正在使用ITextSharp和ASP.NET 1.1动态创建PDF文件。我的流程如下 -

  • 在服务器上创建文件
  • 将浏览器重定向到新创建的PDF 文件,以便显示给用户

我想要做的是在用户浏览器中显示PDF后立即从服务器中删除PDF。 PDF文件很大,因此无法将其保存在内存中,因此需要对服务器进行初始写入。我目前正在使用定期轮询文件然后删除它们的解决方案,但我更喜欢在将文件下载到客户端计算机后立即删除该文件的解决方案。有没有办法做到这一点?

4 个答案:

答案 0 :(得分:6)

您可以使用自己的HttpHandler自行提供文件,而不是将浏览器重定向到创建的文件。然后,您可以在提供文件后立即删除该文件,或者甚至可以在内存中创建该文件。

将PDF文件直接写入客户端:

public class MyHandler : IHttpHandler {
    public void ProcessRequest(System.Web.HttpContext context) {
        context.Response.ContentType = "application/pdf";
        // ...
        PdfWriter.getInstance(document, context.Response.OutputStream);
        // ...

或读取已生成的文件'filename',提供文件,删除它:

context.Response.Buffer = false;
context.Response.BufferOutput = false;
context.Response.ContentType = "application/pdf";

Stream outstream = context.Response.OutputStream;
FileStream instream = 
    new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);

byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = instream.Read(buffer, 0, BUFFER_SIZE)) > 0) {
    outstream.Write(buffer, 0, len);
}
outstream.Flush();
instream.Close();

// served the file -> now delete it 
File.Delete(filename);

我没试过这段代码。这就是我认为它会起作用的方式......

答案 1 :(得分:5)

受f3lix的回答启发(感谢f3lix!)我已经想出了以下的VB.net代码 -

HttpContext.Current.Response.ClearContent()
HttpContext.Current.Response.ClearHeaders()
HttpContext.Current.Response.ContentType = "application/pdf"
HttpContext.Current.Response.TransmitFile(PDFFileName)
HttpContext.Current.Response.Flush()
HttpContext.Current.Response.Close()
File.Delete(PDFFileName)

这看起来有效 - 我使用的'WriteFile'方法对f3lix使用的流方法的效率要低一些吗?有没有比我们的解决方案更有效的方法?

编辑(2009年3月19日)基于以下评论,我将'WriteFile'方法更改为'TransmitFile',因为它似乎将文件以块的形式发送到客户端,而不是将整个文件写入Web服务器的内存中发送。更多信息可以在here找到。

答案 2 :(得分:3)

或者您可以将其返回浏览器而无需写入磁盘:

byte[] pdf;

using (MemoryStream ms = new MemoryStream()) {
    Document doc = new Document();
    PdfWriter.GetInstance(doc, ms);
    doc.AddTitle("Document Title");
    doc.Open();
    doc.Add(new Paragraph("My paragraph."));
    doc.Close();
    pdf = ms.GetBuffer();
}

Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=MyDocument.pdf");
Response.OutputStream.Write(pdf, 0, pdf.Length);

答案 3 :(得分:0)

解决方案:

Response.TransmitFile(PDFFileName)
Response.Flush()
Response.Close()
File.Delete(PDFFileName)

根本不适用于我(文件永远不会对客户端)。读取字节数组并调用Response.BinaryWrite也不是一个选项,因为文件可能很大。是唯一的黑客启动异步进程,等待文件被释放然后删除它?