TIPS 056:バイナリファイルを読み込む(2)

TIPS 056:バイナリファイルを読み込む(2)

FileReaderオブジェクトには、もうひとつバイナリファイルを読み込むための
readAsBinaryStringメソッドが用意されています。
例えば以下は、TIPS 055のサンプルをreadAsBinaryStringメソッドで書き換えたものです。

[リスト04]画像ファイルの内容を表示(readBinary.html)

  <script>
  window.addEventListener('DOMContentLoaded', function() {
    // ファイルが指定されたタイミングで、その内容を表示
    document.querySelector("#file").addEventListener('change', function(e) {
      // File APIを利用できるかをチェック
      if (window.File) {
        // 指定されたファイルを取得
        var input = document.querySelector('#file').files[0];
        // ファイル読み込みの準備
        var reader = new FileReader();
        // ファイルの読み込みに成功したら、その内容を<img id="result">に反映(2)
        reader.addEventListener("load", function(event){
          // バイナリデータを取得
          var raw = reader.result;
          // バイト配列を格納する変数
          var bytes = [];
          // バイナリデータを順に取得(0xffとの論理積でバイト値に変換(1))
          for (var i = 0; i < raw.length; i++){
            bytes[i] = raw.charCodeAt(i) & 0xff;
          }
          // Base64エンコードしたものをData URL形式に整形(2)
          document.querySelector('#result').src = "data:" + input.type 
            + ";base64," + btoa(String.fromCharCode.apply(String, bytes));
        } , true);
        reader.readAsBinaryString(input);
      }
    }, true);
  });
  </script>

readAsBinaryStringメソッドは、生のバイナリデータを取得しますので、サンプルではこれをバイト配列に変換した上で(1)、更にこれを文字列変換し、最終的に、btoaメソッドでBase64エンコードしています(2)。これは、バイナリデータからバイト文字列を得る定型的な流れです。Base64エンコードできてしまえば、あとは「data:[コンテンツタイプ][;base64],データ本体」の構文に従って、Data URLを組み立てるだけです。

サンプルを見てもわかるように、取得したデータをそのまま、

TIPS 057:ファイル読み込みに失敗した場合の処理を定義する

FileReaderオブジェクトにerrorイベントリスナーを登録しておくことで、ファイルの読み込みに失敗した場合に、エラーメッセージの表示などのエラー処理を行えます。

[リスト05]読み込みエラー時にエラーメッセージを表示(readError.html)

  <script>
  window.addEventListener('DOMContentLoaded', function() {
    // ファイルが指定されたタイミングで、その内容を表示
    document.querySelector("#file").addEventListener('change', function(e) {
      // File APIを利用できるかをチェック
      if (window.File) {
        // 指定されたファイルを取得
        var input = document.querySelector('#file').files[0];
        var reader = new FileReader();
        reader.readAsDataURL(input);
        reader.addEventListener('load', function(e) {
          document.querySelector('#result').src = reader.result;
        }, true);
        // 読み込みエラー時の処理
        reader.addEventListener('error', function(e) {
          // エラーコードに対応するメッセージを準備(1)
          var errors = [
            '',
            '指定のファイルが見つかりません。',
            '読み込み権限がありません。',
            '処理が中断されました。',
            '読み込み中にエラーが発生しました。',
            'ファイルサイズが大きすぎます。'
          ];
          // エラーコードに応じてメッセージを表示(2)
          document.querySelector('#err').innerHTML = errors[reader.error.code];
        }, true);
      }
    }, true);
  });
  </script>

errorイベントリスナーの中では、error.codeプロパティでエラーコードにアクセスできます。エラーコードの意味は、以下のとおりです。

表4:error.codeプロパティの値

エラーコード概要
1指定のファイルが存在しない
2権限エラー(読み取り権限を持たないなど)
3ファイルの読み込みを中断された
4読み込み中のエラー
5ファイルサイズが許容上限を超えた

サンプルでは、エラーコード1~5に対応するエラーメッセージを配列errorsにセットしておくことで(1)、codeプロパティの値に応じてメッセージを返しているわけです(2)。例えばエラーコード1で、erros[1]が取り出されます。

TIPS 058:ファイル読み込み時の進捗状況を表示する

読み込みの状況を追跡するには、progressイベントを利用します。progressイベントは、ファイル読み込みの開始から終了までの間、連続して発生するイベントです。

以下では、このprogressイベントを利用して、ファイルの読み込み状況を「●○%読み込み済み」のように、テキストで表示します。

[サンプル]読み込み率をテキスト表示するコード(readProgress.html)

  <!DOCTYPE html>
  <html>
  <head>
  <meta charset="UTF-8" />
  <title>HTML5 TIPS</title>
  <script>
  window.addEventListener('DOMContentLoaded', function() {
      // ファイルが指定されたタイミングで、その内容を表示
      document.querySelector("#file").addEventListener('change', function(e) {
        // 指定されたファイルを取得
        if (window.File) {
        // 指定されたファイルを取得
        var input = document.querySelector('#file').files[0];
        // ファイル読み込みの準備
        var reader = new FileReader();
        // ファイルの読み込みに成功したら、その内容を<img id="result">に反映
        reader.addEventListener('load', function(e) {
          document.querySelector('#result').src = reader.result;
        }, true);
      
        // ファイルの読み込み中に進捗状況を表示
        reader.addEventListener('progress', function(e) {
          // 「ロード済みサイズ÷総サイズ」で読み込み率を求める
          document.querySelector('#prog').innerHTML = 
            Math.floor(e.loaded /e.total * 100);
        }, true);
 
        // ファイルの内容をData URL形式で取得
        reader.readAsDataURL(input);
      }
    }, true);
  });
  </script>
  </head>
  <body>
  ファイル:
  <input id="file" name="file" type="file" />
  <hr />
  <span id="prog" style="color:Blue;">0</span>%読み込み済み
  <img id="result" />
  </body>
  </html>
図4:ファイル読み込みの進捗をパーセント表示

progressイベントリスナーの中では、totalプロパティでファイルの総サイズを、loadedプロパティで読み込み済みのサイズを、それぞれ取得できます。そこでサンプルでは、「loaded ÷ totaled × 100」という式で、読み込み済みのサイズ割合を求めています。progressイベントは、ファイルの読み込み中に連続して発生しますので、サンプルのようなリスナーを設けておくことで、読み込み割合が徐々に増えていく効果を実装しています。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30