Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete dynamically generated PDF file immediately after it has been displayed to user

I'm creating a PDF file on the fly using ITextSharp and ASP.NET 1.1. My process is as follows -

  • Create file on server
  • Redirect browser to newly created PDF file so it is displayed to user

What I'd like to do is delete the PDF from the server as soon it is displayed in the users browser. The PDF file is large so it is not an option to hold it in memory, an initial write to the server is required. I'm currently using a solution that periodically polls for files then deletes them, but I'd prefer a solution that deletes the file immediately after it has been downloaded to the client machine. Is there a way to do this?

like image 964
ipr101 Avatar asked Mar 18 '09 09:03

ipr101


People also ask

How do I stop a PDF from being downloaded and printed?

You can't disable the Download button in your PDF files, and you sure can't prevent the user from choosing Print... in the right-click menu for the entire screen. What you can do is password protect your PDF in Adobe Acrobat. Aside from password protection, their Protect tool also allows you to disable printing.

Can PDF have dynamic content?

Creating a dynamic PDF document is a good way to create an interactive slideshow. You can create interactive documents with buttons, movies and sound clips, hyperlinks, bookmarks, and page transitions. You can also set up documents in InDesign that can be converted to forms in Acrobat.


3 Answers

Instead of redirecting the browser to the created file you could serve the file yourself using you own HttpHandler. Then you could delete the file immediately after you served it or you could even create the file in memory.

Write the PDF file directly to the Client:

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

or read an already generated file 'filename', serve the file, delete it:

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

I didn't try this code. This is just how I think it would work ...

like image 154
f3lix Avatar answered Oct 06 '22 03:10

f3lix


Inspired by f3lix's answer (thanks f3lix!) I've come up with the folowing VB.net code -

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)

This appears to work - is the 'WriteFile' method I've used any less efficent that the stream methods used by f3lix? Is there a method available that's more efficient than either of our solutions?

EDIT (19/03/2009) Based on comments below I've changed 'WriteFile' method to 'TransmitFile' as it appears it sends the file down to client in chunks rather than writing the entire file to the webserver's memory before sending. Further info can be found here.

like image 27
ipr101 Avatar answered Oct 06 '22 03:10

ipr101


Or you could just return it to the browser without writing to disk at all:

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);
like image 24
michaelrp Avatar answered Oct 06 '22 01:10

michaelrp