Open棟梁 wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

.NETによるファイルのダウンロード処理

詳細

  • WWWサーバでファイルを直接Getするか、
  • APサーバでResponseオブジェクトのメソッドを使用して、

HTTPレスポンスにファイルを書き込むことで

ダウンロードが可能になる。

ここでは後者(ASP.NET)の処理方法を説明している。

ダウンロード

Response.Clear();によってHTTPレスポンスのヘッダ&エンティティをクリアし、

  • Content-Disposition(MIMEタイプ)
  • Cache-ControlとPragma(キャッシュ制御)

の再設定が可能。

/// <summary>ページロードのUOCメソッド(個別:初回ロード)</summary>
/// <remarks>実装必須</remarks>
protected override void UOC_FormInit()
{
    // フォーム初期化(初回ロード)時に実行する処理を実装する
    // TODO:

    // HTTPレスポンスのヘッダ&エンティティのクリア
    Response.Clear();

    // HTTPレスポンス ヘッダ再設定

    // MIMEタイプ
    Response.ContentType = "application/pdf";

    // キャッシュ無効化
    Response.Cache.SetCacheability(HttpCacheability.NoCache);

    //こっちは、専用アプリケーションで開く
    //Response.AppendHeader("Content-Disposition", "attachment;filename=test.pdf");
    
    //こっちは、IEからOLEオブジェクトを開く
    Response.AppendHeader("Content-Disposition", "inline;filename=test.pdf");
    
    // HTTPレスポンス エンティティ設定
    Response.WriteFile(
        Path.Combine(
            GetConfigParameter.GetConfigValue("TestFilePath"), "test.pdf"));

    // HTTPレスポンス エンティティ設定の終了
    Response.End(); 
}

ファイルを受信しきらないうちに
クライアントがTCP/IPのコネクションをClose削除した場合、
Response.End();ステートメントで例外 が発生することがある。

System.Web.HttpException: The remote host closed the connection. The error code is 0x80072746.

必要であれば、
Response.End();ステートメントの前後を
Try...Catchで囲んで正常系で終了させる。

テンポラリ・ファイルを削除

また、出力したテンポラリ・ファイルを
HTTPレスポンス エンティティ・ボディに設定した後、
直ちに削除する場合は以下のように実装する。

/// <summary>ページロードのUOCメソッド(個別:初回ロード)</summary>
protected override void UOC_FormInit() {
  // フォーム初期化(初回ロード)時に実行する処理を実装する
  // TODO:
  string fileName ="Winter";

  // tempファイル名にGUIDを使用する。
  string tempFileName = Guid.NewGuid().ToString();
  string tempfilePath = @"C:\temp\" + tempFileName;
  // temp画像を作成する(tif → png変換処理)
  Bitmap bmp = new Bitmap(@"C:\temp\" + fileName + ".tif");
  bmp.Save(tempfilePath, System.Drawing.Imaging.ImageFormat.Png);
  bmp.Dispose();

  // 以下ダウンロード処理(FileStreamを使う)
  // ヘッダのコントロール。
  Response.Clear();
  Response.ContentType = "image/png";
  Response.AppendHeader("Content-Disposition",
    "attachment;filename=" + fileName + ".png");

  // FileStreamでバッファに起こす。
  FileStream fs = null;
  byte[] buf = null;

  try {
    fs = new FileStream(tempfilePath, FileMode.Open, FileAccess.Read);
    int fileSize = (int)fs.Length; // ファイルのサイズ
    buf = new byte[fileSize]; // データ格納用配列
    int readSize; // Readメソッドで読み込んだバイト数
    int remain = fileSize; // 読み込むべき残りのバイト数
    int bufPos = 0; // データ格納用配列内の追加位置

    while (remain > 0) {
      // 1024Bytesずつ読み込む
      readSize = fs.Read(
        buf, bufPos, Math.Min(1024, remain));
      bufPos += readSize;
      remain -= readSize;
    }
  }
  finally {
    // ファイルストリームをクローズ
    fs.Close();
    // ファイルを消去
    File.Delete(tempfilePath);
  }

  // BinaryWriteメソッドを使用。
  Response.BinaryWrite(buf);
  // レスポンスへの書き込みを終了。
  Response.End();
}

サイズの大きなファイルの場合は、
DLエラーの時のオーバーヘッドが大きいのでハマらないかもしれない。

サイズの大きなファイルの場合

Response.WriteFile?ではなく、Response.OutputStream?.Writeを使用する。

参考

ファイルのアップロード

ファイル・ダウンロード処理の問題

マイクロソフト系技術情報 Wiki

アップロード・ダウンロード


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-09-25 (水) 09:47:43 (25d)