2009-03-18 19 views
6

Sto creando un file PDF al volo usando ITextSharp e ASP.NET 1.1. Il mio processo è il seguente -Elimina il file PDF generato dinamicamente subito dopo che è stato visualizzato all'utente

  • Creare file sul server di navigatore
  • reindirizzamento al creato di recente PDF file in modo che viene visualizzato all'utente

Quello che mi piacerebbe fare è eliminare il PDF dal server non appena viene visualizzato nel browser degli utenti. Il file PDF è di grandi dimensioni quindi non è un'opzione per tenerlo in memoria, è necessaria una scrittura iniziale sul server. Attualmente sto usando una soluzione che periodicamente esegue il polling dei file e li elimina, ma preferirei una soluzione che cancelli il file immediatamente dopo che è stato scaricato sul computer client. C'è un modo per fare questo?

+0

si potrebbe verificare che una richiesta di questo file PDF con nome univoco è stato servito con un codice 200 e raccogliere in quel momento ; tuttavia, la tua soluzione iniziale suona "abbastanza bene". Potresti consigliare perché la tua attuale soluzione non funziona, quindi possiamo proporre soluzioni migliori? –

risposta

6

Invece di reindirizzare il browser al file creato, è possibile pubblicare manualmente il file utilizzando il proprio HttpHandler. Quindi è possibile eliminare il file immediatamente dopo averlo servito oppure è persino possibile creare il file in memoria.

scrivere il file PDF direttamente al Cliente:

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

o leggere un file già generato 'filename', servire il file, eliminarlo:

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

non ho provato questo codice Questo è solo come penso che funzionerebbe ...

5

Ispirato dalla risposta di f3lix mi è venuta in mente il codice VB.net folowing (grazie 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) 

Questo sembra funzionare - è il metodo "WriteFile" che ho usato meno efficace dei metodi di streaming usati da f3lix? Esiste un metodo disponibile più efficiente di una delle nostre soluzioni?

EDIT (19/03/2009) Sulla base dei commenti qui sotto ho cambiato metodo 'WriteFile' a 'TransmitFile' come appare si invia il file verso il basso per cliente in pezzi piuttosto che scrivere l'intero file nella memoria del server web prima di inviare. Ulteriori informazioni possono essere trovate here.

+0

Dovresti invece usare TransmitFile. WriteFile carica l'intero file in memoria - TransmitFile lo trasmette. –

+0

Inoltre, impostazione della risposta.Buffer = true kinda va contro TransmitFile, anche se non sono sicuro che TransmitFile ignori il parametro Buffer. –

0

La soluzione:

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

Semplicemente non funziona per me (file non rende al cliente). La lettura in un array di byte e la chiamata a Response.BinaryWrite non è un'opzione perché il file potrebbe essere di grandi dimensioni. L'unico trucco per questo è avviare un processo asincrono che attende il rilascio del file e quindi cancellarlo?

3

Oppure si può semplicemente tornare al browser, senza la scrittura su disco a tutti:

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