LoginSignup
2
1

More than 3 years have passed since last update.

便利ページ:Javascriptでバイナリファイル操作

Last updated at Posted at 2019-09-06

便利ページ:Javascriptでちょっとした便利な機能を作ってみた のシリーズものです。

今回は、Javascsript上でバイナリファイルを開いたり、バイナリファイルに保存したりしてみます。
他の有志のページで、たくさんの情報がありましたので、非常に助かりました。

毎度の通り、デモページとGitHubです。

GitHub
 https://github.com/poruruba/utilities

デモページ
 https://poruruba.github.io/utilities/

バイナリファイルを開く

HTMLのtype="file"のinput要素を使います。
このinputのボタンによりファイルを選択されたイベントをフックし、あとはHTML5のFile機能を使います。

index.html
                <input type="file" v-on:change="binary_open" v-on:click="binary_click"><br>
                <button v-on:click="binary_save()">ファイルに保存</button><br>
                <br>
                <div class="form-inline">
                    <label>改行</label>
                    <select class="form-control" v-model="binary_cr_num">
                        <option value="0">無し</option>
                        <option value="2">2バイト</option>
                        <option value="4">4バイト</option>
                        <option value="8">8バイト</option>
                        <option value="16">16バイト</option>
                    </select>
                    <input type="checkbox" v-model="binary_space">空白 
                    <button class="btn btn-primary" v-on:click="binary_cr()">整形</button><br>
                </div>
                <textarea class="form-control" rows="5" v-model="binary_output"></textarea>

type="file"のファイルが指定されると、Vueの構文でv-on:changeで指定した関数(binary_open)が呼ばれます。
ArrayBufferとして読み出して、読み出しが完了したときに、16進数文字列にして表示させています。

start.js
        binary_open: function(e){
            var file = e.target.files[0];
            var reader = new FileReader();
            reader.onload = (theFile) =>{
                this.binary_output = byteAry2hexStr(new Uint8Array(theFile.target.result));
            };
            reader.readAsArrayBuffer(file);
        },
        binary_click: function(e){
            e.target.value = '';
        },

一方、v-on:clickで関数(binary_click)を指定しています。
これは、一度ファイルを選択した後に、再度同じファイルを選択してもonchangeが呼ばれないため、ファイル選択ボタンを押したときに、以前に選択していたファイルを未選択状態にしています。

バイナリファイルを保存

バイナリファイルの保存は、以下の関数です。

start.js
        binary_save: function(){
            var target = this.binary_output.replace(/\r?\n|\s/g, '');
            var array = hexStr2byteAry(target);
            var buffer = new ArrayBuffer(array.length);
            var dv = new DataView(buffer);
            for( var i = 0 ; i < array.length ; i++ )
                dv.setUint8(i, array[i]);

            var blob = new Blob([buffer], {type: "octet/stream"});
            var url = window.URL.createObjectURL(blob);

            var a = document.createElement("a");
            a.href = url;
            a.target = '_blank';
            a.download = "array.bin";
            a.click();
            window.URL.revokeObjectURL(url);
        },

最初に、改行と空白を削除しています。それは後述する整形を想定してのことです。整形を実行したときに改行やスペースを挿入して表示しているためです。

16進数文字列を整形する

長いバイト列を16進数文字列で表示させると見にくくなります。
そこで、適当に改行を入れたり、1バイトごとに空白を入れたりしています。例えば、16バイトごとに改行を入れるなど。

start.js
        binary_cr: function(){
            var target = this.binary_output.replace(/\r?\n|\s/g, '');
            var array = hexStr2byteAry(target);
            var num_of_interval = Number(this.binary_cr_num);
            if( num_of_interval == 0 ){
                if( this.binary_space )
                    this.binary_output = byteAry2hexStr(array, ' ');
                else
                    this.binary_output = byteAry2hexStr(array);
            }else{
                var str = '';
                for( var i = 0 ; i < array.length ; i += num_of_interval ){
                    if( this.binary_space )
                        str += byteAry2hexStr(array.slice( i, i + num_of_interval ), ' ') + '\n';
                    else
                        str += byteAry2hexStr(array.slice( i, i + num_of_interval )) + '\n';
                }
                this.binary_output = str;
            }
        },

以上

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1