ここでは ASP.NET で、 FileUpload コントロール ( ASP.NET2.0 以降 ) を使用したファイルアップロードと HttpResponse.TransmitFile を使用したファイルダウンロードのサンプルコードを掲載しています。
スポンサーリンク
サンプルで使用するWebフォームには以下のように、FileUpload コントロールと Button コントロールをそれぞれ1つずつ配置しているものとします。
ASPX
<form id="form1" runat="server"> <div> <asp:FileUpload ID="FileUpload1" runat="server" /> <asp:Button ID="Button1" runat="server" Text="Button" /> </div> </form>
ファイルのアップロードとダウンロード
ファイルのアップロードとダウンロードを一度に行っているサンプルです。一度ファイルに保存した後、そのファイルをレスポンスに出力しています。
VB.NET
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click ' ファイルがアップロードされていなければリターン If (FileUpload1.HasFile = False) Then Return '一時ファイルに保存 Dim fpath As String = Path.GetTempFileName FileUpload1.SaveAs(fpath) ' レスポンスを作成して返す(アップロードされたファイルをそのままダウンロード) Dim resp As HttpResponse = HttpContext.Current.Response resp.Clear() resp.ContentType = FileUpload1.PostedFile.ContentType ' コンテントタイプ resp.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(FileUpload1.FileName)) resp.TransmitFile(fpath) resp.Flush() ' 一時ファイルを削除 File.Delete(fpath) End Sub
C#
protected void Button1_Click(object sender, EventArgs e) { // ファイルがアップロードされていなければリターン if (FileUpload1.HasFile == false) { return; } // 一時ファイルに保存 string fpath = Path.GetTempFileName(); FileUpload1.SaveAs(fpath); // レスポンスを作成して返す(アップロードされたファイルをそのままダウンロード) HttpResponse resp = HttpContext.Current.Response; resp.Clear(); resp.ContentType = FileUpload1.PostedFile.ContentType; // コンテントタイプ resp.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(FileUpload1.FileName)); resp.TransmitFile(fpath); resp.Flush(); // 一時ファイルを削除 File.Delete(fpath); }
上記サンプルでは、HttpResponse.TransmitFile メソッドを使用していますが、HttpResponse.WriteFile メソッドと言う同じようなメソッドもあります。両者の違いは、HttpResponse.TransmitFile がサーバメモリにファイルをバッファリングせず出力するために最大 2GB まで出力可能なのに対し、HttpResponse.WriteFile はサーバーメモリにファイルをバッファリングし出力サイズはサーバの状態によって変化します。HttpResponse.TransmitFile と比べると送信可能なファイルサイズはグンと小さくなります。
また、以下のページにもありますように HttpResponse.WriteFile は大きなファイルのダウンロードはできません。また、エラーをサーバプログラムで検出することもできません。エラー検出するには、リンクにあるような回避策をとる必要があるようです。
一時ファイルに保存せずにメモリデータをダウンロードする
上記のサンプルでは、一時ファイルに保存してからダウンロードしましたが、実用上はメモリのデータをそのまま出力するようなことも多いと思います。そのようなときには、以下のように HttpResponse.BinaryWrite メソッドを使用して出力することもできます。
VB.NET
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click ' ファイルがアップロードされていなければリターン If (FileUpload1.HasFile = False) Then Return ' ファイルをメモリーに格納 Dim data(FileUpload1.PostedFile.ContentLength) As Byte FileUpload1.PostedFile.InputStream.Read(data, 0, FileUpload1.PostedFile.ContentLength) ' レスポンスを作成して返す(アップロードされたファイルをそのままダウンロード) Dim resp As HttpResponse = HttpContext.Current.Response resp.Clear() resp.ContentType = FileUpload1.PostedFile.ContentType ' コンテントタイプ resp.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(FileUpload1.FileName)) resp.BinaryWrite(data) End Sub
C#
protected void Button1_Click(object sender, EventArgs e) { // ファイルがアップロードされていなければリターン if (FileUpload1.HasFile == false) { return; } // ファイルをメモリーに格納 Byte[] data = new Byte[FileUpload1.PostedFile.ContentLength]; FileUpload1.PostedFile.InputStream.Read(data, 0, FileUpload1.PostedFile.ContentLength); // レスポンスを作成して返す(アップロードされたファイルをそのままダウンロード) HttpResponse resp = HttpContext.Current.Response; resp.Clear(); resp.ContentType = FileUpload1.PostedFile.ContentType; // コンテントタイプ resp.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(FileUpload1.FileName)); resp.BinaryWrite(data); }