2009-03-18 15 views
6

Tworzę plik PDF w locie za pomocą ITextSharp i ASP.NET 1.1. Mój proces jest następujący -Usuń dynamicznie generowany plik PDF natychmiast po wyświetleniu użytkownikowi

  • Tworzenie pliku na serwerze przeglądarka
  • Przekierowanie na nowo utworzony plik PDF więc jest wyświetlane użytkownikowi

Co chciałbym zrobić, to usunąć PDF z serwera, gdy tylko pojawi się w przeglądarce użytkowników. Plik PDF jest duży, więc nie jest opcją przechowywania go w pamięci, wymagany jest wstępny zapis na serwerze. Obecnie używam rozwiązania, które okresowo odpytuje za pliki, a następnie usuwa je, ale wolę rozwiązanie, które usuwa plik natychmiast po pobraniu go na komputer klienta. Czy jest jakiś sposób na zrobienie tego?

+0

Można sprawdzić, że wniosek o tym jednoznacznie nazwie pliku PDF było podawane z kodem 200 i czerpać ją w tym czasie ; jednak twoje początkowe rozwiązanie brzmi "wystarczająco dobrze". Czy możesz doradzić, dlaczego Twoje obecne rozwiązanie nie działa, abyśmy mogli zaproponować lepsze rozwiązania? –

Odpowiedz

6

Zamiast przekierowywać przeglądarkę do utworzonego pliku, możesz samemu przesłać plik używając własnego HttpHandler. Następnie możesz usunąć plik natychmiast po wykonaniu usługi lub nawet utworzyć plik w pamięci.

zapisać plik PDF bezpośrednio do Klienta:

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

lub odczytać już wygenerowany plik 'nazwa_pliku', służyć plik, usuń go:

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

nie próbowałem ten kod. To jest po prostu jak myślę, że to działa ...

5

Zainspirowany odpowiedź f3lix za Mam wymyślić folowing kodu VB.NET (dzięki 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) 

to wydaje się działać - czy metoda "WriteFile" użyłem jakiejś mniej wydajnej metody strumieniowej używanej przez f3lix? Czy istnieje dostępna metoda, która jest bardziej wydajna niż którekolwiek z naszych rozwiązań?

EDYCJA (19/03/2009) Na podstawie komentarzy poniżej zmieniłem metodę "WriteFile" na "TransmitFile", ponieważ wygląda na to, że wysyła plik do klienta w porcjach, zamiast zapisywać cały plik w pamięci serwera WWW przed wysłaniem. Więcej informacji można znaleźć here.

+0

Zamiast tego należy użyć pliku TransmitFile. WriteFile ładuje cały plik do pamięci - TransmitFile je przesyła. –

+0

Ponadto ustawienie odpowiedzi.Buffer = true kinda idzie przeciwko TransmitFile, choć nie jestem pewien, czy TransmitFile zignoruje parametr Buffer. –

0

Rozwiązanie:

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

po prostu nie działa dla mnie (plik nigdy nie dotrze do klienta). Odczyt w tablicy bajtów i wywoływanie Response.BinaryWrite nie jest opcją, ponieważ plik może być duży. Czy jest to jedyny hack, aby rozpocząć asynchroniczny proces, który czeka na zwolnienie pliku, a następnie go usunąć?

3

Albo może po prostu zwrócić go do przeglądarki bez zapisywania na dysku w ogóle:

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); 
Powiązane problemy