2009-03-18 28 views
6

Tôi đang tạo tệp PDF khi đang chạy bằng cách sử dụng ITextSharp và ASP.NET 1.1. quá trình của tôi là như sau -Xóa tệp PDF được tạo động ngay lập tức sau khi nó được hiển thị cho người dùng

  • Tạo tập tin trên máy chủ của trình duyệt
  • Redirect để vừa tạo PDF tập tin vì vậy nó được hiển thị cho người dùng

Những gì tôi muốn làm là xóa PDF từ máy chủ ngay khi nó được hiển thị trong trình duyệt của người dùng. Tập tin PDF lớn nên không phải là một tùy chọn để giữ nó trong bộ nhớ, một yêu cầu viết ban đầu cho máy chủ là bắt buộc. Tôi hiện đang sử dụng một giải pháp định kỳ thăm dò cho các tập tin sau đó xóa chúng, nhưng tôi muốn một giải pháp mà xóa các tập tin ngay lập tức sau khi nó đã được tải xuống máy khách. Có cách nào để làm việc này không?

+0

Bạn có thể kiểm tra xem yêu cầu tập tin PDF được đặt tên độc đáo này được ăn kèm với một mã số 200 và gặt hái nó tại thời điểm đó ; tuy nhiên, giải pháp ban đầu của bạn nghe có vẻ "đủ tốt". Bạn có thể giải thích tại sao giải pháp hiện tại của bạn không hoạt động, vì vậy chúng tôi có thể đề xuất các giải pháp tốt hơn? –

Trả lời

6

Thay vì chuyển hướng trình duyệt tới tệp được tạo, bạn có thể tự mình phục vụ tệp bằng cách sử dụng HttpHandler của riêng bạn. Sau đó, bạn có thể xóa tệp ngay sau khi bạn đã phân phát hoặc thậm chí bạn có thể tạo tệp trong bộ nhớ.

Viết các tập tin PDF trực tiếp đến Chủ đầu tư:

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

hoặc đọc một tập tin đã được tạo ra 'filename', phục vụ các tập tin, xóa nó:

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

Tôi không cố gắng mã này. Đây chỉ là cách tôi nghĩ rằng nó sẽ làm việc ...

5

Lấy cảm hứng từ câu trả lời f3lix của tôi đã đi lên với mã VB.net folowing (nhờ 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) 

Điều này dường như làm việc - là phương pháp 'WriteFile' tôi đã sử dụng ít hiệu quả hơn khi các phương thức stream được sử dụng bởi f3lix? Có phương pháp nào có hiệu quả hơn cả hai giải pháp của chúng tôi không?

EDIT (19/03/2009) Dựa trên các nhận xét bên dưới, tôi đã thay đổi phương thức 'WriteFile' thành 'TransmitFile' khi nó xuất hiện gửi tệp xuống máy khách theo khối chứ không phải ghi toàn bộ tệp vào bộ nhớ của máy chủ web trước khi gửi. Thông tin thêm có thể được tìm thấy here.

+0

Bạn nên sử dụng TransmitFile thay thế. WriteFile tải toàn bộ tập tin vào bộ nhớ - TransmitFile truyền tải nó. –

+0

Ngoài ra, hãy đặt Trả lời.Buffer = true kinda đi ngược lại TransmitFile, mặc dù tôi không chắc TransmitFile có bỏ qua tham số Buffer hay không. –

0

Giải pháp:

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

Đơn giản chỉ cần không làm việc cho tôi (tập tin không bao giờ làm cho nó đến khách hàng). Đọc trong mảng byte và gọi Response.BinaryWrite không phải là một tùy chọn vì tệp có thể lớn. Là hack duy nhất cho điều này để bắt đầu một quá trình không đồng bộ chờ đợi cho các tập tin được phát hành và sau đó xóa nó?

3

Hoặc bạn chỉ có thể trả lại cho trình duyệt mà không cần viết vào đĩa tại tất cả:

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); 
Các vấn đề liên quan