6

我正在使用 ITextSharp 和 ASP.NET 1.1 即时创建 PDF 文件。我的流程如下——

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

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

4

4 回答 4

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);
        // ...

或读取已生成的文件“文件名”,提供文件,删除它:

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);

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

于 2009-03-18T10:01:24.003 回答
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”,因为它似乎将文件以块的形式发送到客户端,而不是在发送之前将整个文件写入网络服务器的内存。更多信息可以在这里找到。

于 2009-03-18T10:42:46.027 回答
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);
于 2010-01-22T15:37:05.643 回答
0

解决方案:

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

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

于 2009-05-12T21:00:33.297 回答