我正在使用 ITextSharp 和 ASP.NET 1.1 即时创建 PDF 文件。我的流程如下——
- 在服务器上创建文件
- 将浏览器重定向到新创建的 PDF 文件,以便向用户显示
我想做的是在用户浏览器中显示 PDF 后立即从服务器中删除它。PDF 文件很大,因此不能将其保存在内存中,需要对服务器进行初始写入。我目前正在使用定期轮询文件然后删除它们的解决方案,但我更喜欢在文件下载到客户端计算机后立即删除文件的解决方案。有没有办法做到这一点?
我正在使用 ITextSharp 和 ASP.NET 1.1 即时创建 PDF 文件。我的流程如下——
我想做的是在用户浏览器中显示 PDF 后立即从服务器中删除它。PDF 文件很大,因此不能将其保存在内存中,需要对服务器进行初始写入。我目前正在使用定期轮询文件然后删除它们的解决方案,但我更喜欢在文件下载到客户端计算机后立即删除文件的解决方案。有没有办法做到这一点?
您可以使用自己的 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);
我没有尝试这段代码。这就是我认为它会起作用的方式......
受 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”,因为它似乎将文件以块的形式发送到客户端,而不是在发送之前将整个文件写入网络服务器的内存。更多信息可以在这里找到。
或者你可以直接将它返回给浏览器而不写入磁盘:
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);
解决方案:
Response.TransmitFile(PDFFileName)
Response.Flush()
Response.Close()
File.Delete(PDFFileName)
根本不适合我(文件永远不会发送给客户)。读取字节数组并调用 Response.BinaryWrite 也不是一种选择,因为文件可能很大。这是唯一的黑客启动等待文件被释放然后删除它的异步进程吗?