2009-03-18 9 views
6

Ich erstelle eine PDF-Datei im Handumdrehen mit ITextSharp und ASP.NET 1.1. Mein Prozess ist wie folgt -Löschen Sie die dynamisch generierte PDF-Datei sofort, nachdem sie dem Benutzer angezeigt wurde

  • erstellen Datei auf dem Server
  • Redirect Browser neu PDF erstellt Datei, so dass es
an Benutzer angezeigt wird

Was ich die PDF tun möchten, ist löschen vom Server, sobald es im Browser des Benutzers angezeigt wird. Die PDF-Datei ist groß, so dass es nicht möglich ist, sie im Speicher zu halten, ein erstes Schreiben auf den Server ist erforderlich. Ich verwende derzeit eine Lösung, die regelmäßig nach Dateien fragt und sie dann löscht, aber ich bevorzuge eine Lösung, die die Datei sofort löscht, nachdem sie auf den Client-Rechner heruntergeladen wurde. Gibt es eine Möglichkeit, dies zu tun?

+0

Sie überprüfen können, dass eine Anfrage für diese eindeutig benannte PDF-Datei mit einem 200-Code serviert wurde und ernten es zu dieser Zeit ; Ihre anfängliche Lösung klingt jedoch "gut genug". Können Sie uns mitteilen, warum Ihre derzeitige Lösung nicht funktioniert, damit wir bessere Lösungen vorschlagen können? –

Antwort

6

Anstatt den Browser auf die erstellte Datei umzuleiten, können Sie die Datei selbst mit Ihrem eigenen HttpHandler bedienen. Dann könnten Sie die Datei sofort löschen, nachdem Sie sie bedient haben, oder Sie könnten die Datei sogar im Speicher erstellen.

Schreiben Sie die PDF-Datei direkt an den Auftraggeber:

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

oder auf eine bereits erstellte Datei 'Dateiname', dienen dazu, die Datei lesen, löschen:

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

ich nicht versuchen, dieser Code. Dies ist nur, wie ich denke, es würde funktionieren ...

5

Inspiriert von f3lix Antwort Ich habe mit dem Folowing VB.net Code kommt (dank f3lix!) -

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) 

Dies scheint zu funktionieren - Ist die 'WriteFile'-Methode, die ich verwende, weniger effizient als die von f3lix verwendeten Stream-Methoden? Gibt es eine Methode, die effizienter ist als jede unserer Lösungen?

BEARBEITEN (19/03/2009) Basierend auf den Kommentaren unten habe ich 'WriteFile' Methode auf 'TransmitFile' geändert, wie es scheint, sendet es die Datei in den Chunks an den Client, anstatt die gesamte Datei auf den Speicher des Webservers zu schreiben vor dem Absenden. Weitere Informationen finden Sie unter here.

+0

Sie sollten stattdessen TransmitFile verwenden. WriteFile lädt die gesamte Datei in den Speicher - TransmitFile streamt sie. –

+0

Einstellung der Antwort.Buffer = true geht gegen TransmitFile, obwohl ich nicht sicher bin, ob TransmitFile den Buffer-Parameter ignoriert. –

0

Die Lösung:

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

einfach nicht für mich arbeiten (Datei macht es nie zu Client). Das Lesen in einem Bytearray und das Aufrufen von Response.BinaryWrite ist ebenfalls keine Option, da die Datei möglicherweise groß ist. Ist der einzige Hack dafür, einen asynchronen Prozess zu starten, der darauf wartet, dass die Datei freigegeben wird, und sie dann zu löschen?

3

Oder Sie könnten es nur an den Browser zurück, ohne überhaupt auf der Festplatte zu schreiben:

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