Удалите динамически сгенерированный PDF-файл сразу после его отображения пользователю - PullRequest
6 голосов
/ 18 марта 2009

Я создаю файл PDF на лету, используя ITextSharp и ASP.NET 1.1. Мой процесс выглядит следующим образом -

  • Создать файл на сервере
  • Перенаправить браузер на вновь созданный PDF файл, так что он отображается для пользователя

Я хотел бы удалить PDF-файл с сервера, как только он отобразится в браузере пользователя. Файл PDF имеет большой размер, поэтому его нельзя хранить в памяти, требуется первоначальная запись на сервер. В настоящее время я использую решение, которое периодически опрашивает файлы, затем удаляет их, но я бы предпочел решение, которое удаляет файл сразу после его загрузки на клиентский компьютер. Есть ли способ сделать это?

Ответы [ 4 ]

6 голосов
/ 18 марта 2009

Вместо того, чтобы перенаправлять браузер на созданный файл, вы можете обработать файл самостоятельно, используя собственный HttpHandler. Затем вы можете удалить файл сразу после его обработки или даже создать файл в памяти.

Напишите файл PDF непосредственно клиенту:

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

или прочитайте уже сгенерированный файл 'filename', обслужите файл, удалите его:

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

Я не пробовал этот код. Вот как я думаю, это будет работать ...

5 голосов
/ 18 марта 2009

Вдохновленный ответом f3lix (спасибо f3lix!) Я придумал следующий код VB.net -

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)

Кажется, это работает - метод «WriteFile», который я использовал, менее эффективен, чем потоковые методы, используемые f3lix? Есть ли способ, который более эффективен, чем любое из наших решений?

РЕДАКТИРОВАТЬ (19/03/2009) Исходя из комментариев ниже, я изменил метод WriteFile на TransmitFile, так как кажется, что он отправляет файл клиенту порциями, а не записывает весь файл в память веб-сервера перед отправка. Дополнительную информацию можно найти здесь .

3 голосов
/ 22 января 2010

Или вы можете просто вернуть его в браузер, не записывая на диск вообще:

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);
0 голосов
/ 13 мая 2009

Решение:

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

Просто у меня не работает (файл никогда не доходит до клиента). Чтение в байтовом массиве и вызов Response.BinaryWrite также не вариант, так как файл может быть большим. Является ли единственным способом для этого запустить асинхронный процесс, который ожидает выпуска файла, а затем удалить его?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...