[[Open棟梁>https://github.com/OpenTouryoProject]] wiki

-[[戻る>アップロード・ダウンロード]]

*目次 [#b30c0350]
#contents

*概要 [#j59383d5]
.NETによるファイルのダウンロード処理

*詳細 [#qb6de0f1]
-WWWサーバ上のファイルを直接Getするか、
-APサーバ側でResponseオブジェクトのメソッドを使用して、HTTPレスポンスにファイルを書き込むことで

ダウンロードが可能。

ここでは後者の処理方法を説明している。

**ダウンロード [#aa618f55]
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で囲んで正常系で終了させる。

**テンポラリ・ファイルを削除 [#mb8b9d2c]
また、出力したテンポラリ・ファイルを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エラーの時のオーバーヘッドが大きいのでハマらないかもしれない。

**サイズの大きなファイルの場合 [#kb68f121]
Response.WriteFileではなく、Response.OutputStream.Writeを使用する。

-PRB: Response.WriteFile、サイズの大きいファイルをダウンロードできません。~
https://support.microsoft.com/ja-jp/kb/812406

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS