HTML5 File API を使ってファイル読み込み

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

HTML5 で追加された File API. これを使えば ローカルファイルの情報, 中身を取得して JavaScript でいじることができます. 今後, HTML5 の普及とクラウド化が進むにつれて重要な機能になることは間違いありません. サンプルを作ってみたのでよかったらぜひ. ドラッグ & ドロップにも対応しているよん♪♪

Chrome でローカル上で作業する場合, セキュリティ上ドラッグ & ドロップに反応しない場合があります. その場合, Chromeの起動オプションに –allow-file-access-from-files を指定することで読み込めるようになります.

SAMPLE And DATA

サンプルはこちらで見ることができます.

ファイル読み込みボタンを押すとファイルエクスプローラが表示されるのでテキストファイルなり何なり選んでください. するとそのファイルの情報と中身を読み込んで表示します. ドラッグ & ドロップにも対応しているので テキストエリアにドロップしても同じ動作が確認できると思います.

サンプルデータのダウンロードはここから!!

CODE

今回のサンプル全体のコードです.

<!DOCTYPE html>

<html>
    <head>
        <meta charset="utf-8">
        <title>File API</title>
        <style type="text/css">
            label {
                width : 200px;
            }
        </style>
        <script>
            var $id = function(id) { return document.getElementById(id); }
            var $class = function(c, n) { n=n||0; return document.getElementsByClassName(c)[n]; }
            var $classes = function(c)  { return document.getElementsByClassName(c); }
            
            window.onload = function()
            {
                // read ボタンを押した際に実行する関数を登録
                $id("read-button").addEventListener("change", onChangeFile, false);
                // ドロップ時イベントを登録
                $id("ta").addEventListener("dragover", onCancel, false);
                $id("ta").addEventListener("dragenter", onCancel, false);
                $id("ta").addEventListener("drop", onDropFile, false);
            };
            
            // ファイル変更時イベント
            var onChangeFile = function(e)
            {
                // File オブジェクトを取得
                var file = e.target.files[0];
                // ファイル読み込み
                readFile(file);
            };
            
            // ファイルドロップ時イベント
            var onDropFile = function(e)
            {
                e.preventDefault();
                // File オブジェクトを取得
                var file = e.dataTransfer.files[0];
                // ファイル読み込み
                readFile(file);
            };
            
            // デフォル処理をキャンセル
            var onCancel = function(e)
            {
                if(e.preventDefault) { e.preventDefault(); }
                return false;
            };
            
            // ファイル読み込み
            var readFile = function(file)
            {
                var func_name = $id("func-name").value;    // 関数名を取得
                var encode_type = $id("encode-type").value;// エンコードタイプを取得
                if (encode_type=="default") encode_type = undefined;
                
                // ファイルの情報を表示
                $id("file-name").innerHTML = file.name; // ファイル名
                $id("file-size").innerHTML = file.size; // ファイルサイズ
                $id("file-type").innerHTML = file.type; // ファイルタイプ
                
                // 中身を読み込む
                var reader = new FileReader();                  // ファイルリーダー生成
                // ロード関数登録
                reader.onload = function(e) {
                    // 読み込んだファイルの中身をテキストエリアにセット
                    $id("ta").value = e.target.result;
                };
                
                // テキストとしてファイルを読み込む
                // reader.readAsText(file);
                // セレクトフォームで選択している関数名でファイル読み込み
                reader[func_name](file, encode_type);
            };
            
        </script>
    </head>
    <body>
        <h1>File API</h1>
        
        <p>Name : <span id="file-name">????</span></p>
        <p>Size : <span id="file-size">????</span></p>
        <p>Type : <span id="file-type">????</span></p>
        <p>Value : </p>
        <textarea id="ta" cols=64 rows=16></textarea>
        <br />
        
        <hr />
        
        <label>
            Func Name : 
            <select id="func-name">
                <option value="readAsText">readAsText</option>
                <option value="readAsDataURL">readAsDataURL</option>
                <option value="readAsArrayBuffer">readAsArrayBuffer</option>
                <option value="readAsBinaryString">readAsBinaryString</option>
            </select>
        </label>
        <br />
        
        <label>
            Encode Type : 
            <select id="encode-type">
                <option value="default">default</option>
                <option value="utf-8">utf-8</option>
                <option value="shift-jis">shift-jis</option>
            </select>
        </label>
        <br />
        
        <input id="read-button" type="file" />
    </body>
</html>

FileReader について

FileReader オブジェクトは, ファイルを読み込むためのオブジェクトです. ファイルを読み込むための関数は次の4つ.

  • readAsText(blob, encoding)
  • readAsDataURL(blob)
  • readAsBinaryString(blob)
  • readAsArrayBuffer(blob)

主によく使うのは readAsText と readAsDataURL になるかと思います.

readAsText はファイルオブジェクトとエンコードタイプを引数に取り, 単純にファイルを読み込みます.

readAsDataURL はファイルオブジェクトを引数に取り, 読み込んだデータを Data URL スキームとして出力します. つまり readAsDataURL で読み込んだデータを Image や Audio の src に渡せばそのまま読み込むことができます. 今後, 使い道がかなりありそうなメソッドです!!

readAsBinaryString は名前の通りバイナリデータとして読み込みます.

readAsArrayBuffer は ArrayBuffer を返します. 使い道はよくわかりませんw

詳しいことはこちらに載っています.公式サイトなので英語ですが…

実際に使っているのは下記のコード部分です. 上記の関数の4つのどれかを実行すると, 読み込みが始まり, 終了すると onload イベントが走ります. そこに登録していた関数に引数として渡されるイベントオブジェクトの target.result の中にデータが入っています.

// 中身を読み込む
var reader = new FileReader();                  // ファイルリーダー生成
// ロード関数登録
reader.onload = function(e) {
    // 読み込んだファイルの中身をテキストエリアにセット
    $id("ta").value = e.target.result;
};

// テキストとしてファイルを読み込む
reader.readAsText(file);

ドラッグ & ドロップについて

ドラッグ & ドロップでテキストファイルを読み込むには, まず dragover と dragenter のデフォルと機能をオフにします. オフにするには, addEventListener の場合 イベントオブジェクトの preventDefault を実行するだけでオフにできます. on~ で登録する場合 返り値をfalseにすればオフになります.

// ドロップ時イベントを登録
$id("ta").addEventListener("dragover", onCancel, false);
$id("ta").addEventListener("dragenter", onCancel, false);
$id("ta").addEventListener("drop", onDropFile, false);

そしてドロップしたファイルオブジェクトの取得方法ですが, drop イベントに登録した関数に渡されるイベントオブジェクトに dataTransfer.files[0] として入っているのでそのオブジェクトを FileReader に渡せば内容を読み込めます.

// ファイルドロップ時イベント
var onDropFile = function(e)
{
    e.preventDefault();
    // File オブジェクトを取得
    var file = e.dataTransfer.files[0];
    // ファイル読み込み
    readFile(file);
};

以上 HTML5 File API サンプルでした~

参考サイト

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT