ここでは 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);
}