2009-03-18 18 views
6

ITextSharpとASP.NET 1.1を使用してオンザフライでPDFファイルを作成しています。次のように私のプロセスがある - 私が何をしたいのですがどのようなユーザー ユーザに表示された直後に動的に生成されたPDFファイルを削除する

に表示されるように

  • は、新しく作成されたPDF ファイルにサーバー上
  • リダイレクトブラウザのファイルを作成してPDFを削除していますサーバからすぐにユーザブラウザに表示されます。 PDFファイルはサイズが大きいので、メモリに保持するオプションではないため、サーバーへの最初の書き込みが必要です。私は現在、定期的にファイルをポーリングして削除するソリューションを使用していますが、クライアントマシンにダウンロードされた直後にファイルを削除するソリューションを希望します。これを行う方法はありますか?

+0

あなたはこの一意の名前のPDFファイルのための要求は200のコードを添えたことを確認し、その時点でそれを享受でき;しかし、あなたの初期のソリューションは「十分に良い」と聞きます。あなたの現在のソリューションがなぜ機能していないのかアドバイスできますか?もっと良いソリューションを提案できますか? –

答えて

6

ブラウザを作成したファイルにリダイレクトする代わりに、自分でHttpHandlerを使用してファイルを提供することができます。その後、ファイルを提供した直後にファイルを削除することもできますし、メモリ内にファイルを作成することもできます。

クライアントに直接PD​​Fファイルを書く:

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

か、既に生成されたファイル 'ファイル名' を読んで、それを削除し、ファイルを提供:

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

私は試していませんこのコード。これは...私はそれが仕事だと思うどれだけf3lixの答えに触発さ

5

である私はfolowing VB.netコードを作ってみた(感謝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) 

これが動作するように見えます - 'WriteFile'メソッドです。私はf3lixで使用されているストリームメソッドより効率が悪いですか?どちらのソリューションより効率的な方法がありますか?

EDIT(19/03/2009)「WriteFile」メソッドを「TransmitFile」に変更しました。ファイル全体をWebサーバーのメモリに書き込むのではなく、チャンクでクライアントに送信するようです送信する前に。さらに詳しい情報はhereです。

+0

代わりにTransmitFileを使用する必要があります。 WriteFileはファイル全体をメモリにロードします。 - TransmitFileはそれをストリームします。 –

+0

さらに、Responseを設定します。TransmitFileがBufferパラメータを無視するかどうかわかりませんが、Buffer = true kindaはTransmitFileに対抗します。 –

0

ソリューション:

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

は、単純に(ファイルがクライアントにそれを作ることはありません)私のために動作しません。バイト配列で読み込み、Response.BinaryWriteを呼び出すことは、ファイルが大きくなる可能性があるため、オプションではありません。このファイルを解放して削除するのを待つ非同期プロセスを開始するための唯一のハックですか?

3

それとも、ただのすべてのディスクに書き込むことなく、ブラウザにそれを返すことができます:

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); 
関連する問題