[ ASP.NET ] ファイルのアップロードとダウンロード ( FileUpload / HttpResponse.TransmitFile )

Pocket

ここでは 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);
    }
参考
スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *