2009-03-18 17 views
6

Estoy creando un archivo PDF sobre la marcha usando ITextSharp y ASP.NET 1.1. Mi proceso es el siguiente -Borrar el archivo PDF generado dinámicamente inmediatamente después de que se haya mostrado al usuario

  • Crear archivo en el servidor del navegador
  • redirección de nueva creación PDF archivo por lo que se muestra al usuario

Lo que me gustaría hacer es eliminar el PDF desde el servidor tan pronto como se muestre en el navegador de los usuarios. El archivo PDF es grande, por lo que no es una opción para mantenerlo en la memoria, se requiere una escritura inicial en el servidor. Actualmente estoy usando una solución que periódicamente busca los archivos y luego los elimina, pero preferiría una solución que elimine el archivo inmediatamente después de que se haya descargado a la máquina del cliente. ¿Hay alguna forma de hacer esto?

+0

se puede comprobar que una solicitud de este archivo PDF con un nombre único fue servido con un código 200 y cosechar en ese momento ; sin embargo, su solución inicial suena "lo suficientemente buena". ¿Podría decirnos por qué su solución actual no funciona, para que podamos proponer mejores soluciones? –

Respuesta

6

En lugar de redirigir el navegador al archivo creado, usted mismo podría servir el archivo utilizando su propio HttpHandler. Luego podría eliminar el archivo inmediatamente después de haberlo servido o incluso podría crear el archivo en la memoria.

escribir el archivo PDF directamente 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 leer un archivo ya generado 'nombre', sirven el archivo, 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); 

no lo probé este código Esto es lo que creo que funcionaría ...

5

Inspirado por la respuesta de f3lix se me ha ocurrido con el código de VB.net folowing (gracias 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) 

Esto parece funcionar - ¿El método 'WriteFile' que he usado es menos eficiente que los métodos de transmisión utilizados por f3lix? ¿Hay algún método disponible que sea más eficiente que cualquiera de nuestras soluciones?

EDITAR (19/03/2009) Basado en los comentarios a continuación, cambié el método 'WriteFile' a 'TransmitFile', ya que parece que envía el archivo al cliente en fragmentos en lugar de escribir todo el archivo en la memoria del servidor web antes de enviar. Se puede encontrar más información en here.

+0

Debería usar TransmitFile en su lugar. WriteFile carga todo el archivo en la memoria: TransmitFile lo transmite. –

+0

Además, estableciendo Respuesta.Buffer = cierto algo va en contra de TransmitFile, aunque no estoy seguro si TransmitFile ignorará el parámetro Buffer. –

0

La solución:

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

simplemente no funciona para mí (archivo nunca llega al cliente). Leer en una matriz de bytes y llamar a Response.BinaryWrite tampoco es una opción, ya que el archivo puede ser grande. ¿Es el único truco para que esto comience un proceso asíncrono que espera a que se lance el archivo y luego lo elimine?

3

O simplemente se podría volver al navegador sin tener que escribir en el disco en absoluto:

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