情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsのバッファについて

バッファとは

バッファとはメモリ上に確保される、バイナリデータを格納するための領域です。

バッファは作成時に長さを指定し、作成後に長さを変更することはできません

Node.jsではBufferクラスとして提供されています。

以後Bufferクラスのインスタンスをbufと表記します。

文字コード

バッファは文字列を格納するために使用することもできます。

文字列はバッファ内でバイナリデータとして格納されますので、バッファには任意の文字コードの文字列を格納することができます。

バッファが標準で対応している文字コードには下のようなものがあります。

  • ascii・・・ASCIIです。
  • utf-8・・・UTF-8です。
  • utf16le・・・UTF-16LEです。
  • ucs2・・・utf16leと同じです。
  • base64・・・Base64です。
  • binary・・・Latin-1です。
  • hex・・・16進数文字列です。

これらの文字コードの文字列に関してはバッファの標準の関数を使用してバッファから読み込んだり、バッファに書き込んだりすることができます。

その他の文字コードの文字列に関しては直接文字列として読み書きするのではなく、バイナリデータとして読み書きする必要があります。

バッファの作成

バッファを作成するために幾つかの関数が提供されています。

初期化バッファ

データで初期化したバッファを作成するにはBuffer.alloc関数を使用します。

var buf = Buffer.alloc(16, 0);
var buf = Buffer.alloc(16, 'xxx', 'utf-8');
var buf = Buffer.alloc(16, buf);

第1引数にバッファの長さをバイト単位で指定します。この長さは0からbufferモジュールのbuffer.kMaxLengthまでの値でなければなりません。

第2引数にデータを指定します。バイトか文字列かバッファを指定します。この引数は指定しなくても構いません。デフォルトは0です。

第3引数にデータの文字コードを指定します。この引数は指定しなくても構いません。デフォルトはutf-8です。ただし、データが文字列でない場合には無視されます。

返り値としてバッファが得られます。

未初期化バッファ

初期化していないバッファを作成するにはBuffer.allocUnsafe関数かBuffer.allocUnsafeSlow関数を使用します。

バッファの作成において予め確保されている共有メモリプールの領域を使用しても良い場合にはBuffer.allocUnsafe関数を使用し、使用してはならない場合にはBuffer.allocUnsafeSlow関数を使用します。

バッファの長さがBuffer.poolSizeの半分以下である場合にはバッファの作成において予め確保されている共有メモリプールの領域が使用される可能性があります。

共有メモリプールの領域を使用した場合には使用しなかった場合に比べてバッファの作成は高速となります

var buf = Buffer.allocUnsafe(16);
var buf = Buffer.allocUnsafeSlow(16);

第1引数にバッファの長さをバイト単位で指定します。この長さは0からbufferモジュールのbuffer.kMaxLengthまでの値でなければなりません。

返り値としてバッファが得られます。

なお、--zero-fill-buffersコマンドラインオプションを付加してNode.jsを起動した場合には関数名に反して0で初期化したバッファが返りますので注意してください。

バイト配列を基にしたバッファ

バイト配列を基にしたバッファを作成するにはBuffer.from関数を使用します。

この関数はバイト配列の全てのバイトをバッファのデータとして順番に格納します。

var buf = Buffer.from([0, 1]);

第1引数にバイト配列を指定します。

返り値としてバッファが得られます。

ArrayBufferクラスのインスタンスを基にしたバッファ

ArrayBufferクラスのインスタンスを基にしたバッファを作成するにはBuffer.from関数を使用します。

この関数はArrayBufferクラスのインスタンスのバッファの全部又は一部をBufferクラスのインスタンスに変換します。

var arrayBuffer = new ArrayBuffer(16);

var buf = Buffer.from(arrayBuffer, 0, 16);

第1引数にArrayBufferクラスのインスタンスを指定します。

第2引数にオフセットを指定します。この引数は指定しなくても構いません。デフォルトは0です。

第3引数に長さをバイト単位で指定します。この引数は指定しなくても構いません。デフォルトはArrayBufferクラスのインスタンスのバッファの長さからオフセットを差し引いたものです。

返り値としてバッファが得られます。

バッファを基にしたバッファ

バッファを基にしたバッファを作成するにはBuffer.from関数を使用します。

この関数はバッファのデータをコピーします。

var buf = Buffer.from(buf);

第1引数にバッファを指定します。

返り値としてバッファが得られます。

文字列を基にしたバッファ

文字列を基にしたバッファを作成するにはBuffer.from関数を使用します。

この関数は文字列のデータをバッファのデータとして格納します。

var buf = Buffer.from('xxx', 'utf-8');

第1引数に文字列を指定します。

第2引数に文字コードを指定します。この引数は指定しなくても構いません。デフォルトはutf-8です。

返り値としてバッファが得られます。

インデックスによるアクセス

バッファのバイトには配列のようにインデックスによりアクセスすることができます。

var byte = buf[0];

buf[0] = 0;

イテラブル

バッファはイテラブルでもあります。

インデックスとバイトのイテラブル

バッファのインデックスとバイトから成る配列から成るイテラブルを取得するにはbuf.entries関数を使用します。

var entries = buf.entries();

インデックスのイテラブル

バッファのインデックスから成るイテラブルを取得するにはbuf.keys関数を使用します。

var keys = buf.keys();

バイトのイテラブル

バッファのバイトから成るイテラブルを取得するにはbuf.values関数を使用します。

var values = buf.values();

バッファの長さ

buf.lengthにはバッファの長さがバイト単位で格納されています。

var length = buf.length;

バッファであるかチェック

オブジェクトがバッファであるかチェックするにはBuffer.isBuffer関数を使用します。

var isBuffer = Buffer.isBuffer(xxx);

第1引数にオブジェクトを指定します。

返り値としてオブジェクトがバッファであるかが真偽値として得られます。

バッファが等しいかチェック

2つのバッファのデータが同じであるかチェックするにはbuf.equals関数を使用します。

var equals = buf.equals(buf2);

第1引数にバッファを指定します。

返り値として2つのバッファのデータが同じであるかが真偽値として得られます。

JSON文字列への変換

バッファをJSON文字列に変換するにはbuf.toJSON関数を使用します。

var json = buf.toJSON();

返り値としてJSON文字列が得られます。

サンプルコード1

buffer.js

var buf1 = Buffer.alloc(16, 1);
var buf2 = Buffer.alloc(16, 'foo');
var buf3 = Buffer.alloc(32, buf2);
var buf4 = Buffer.allocUnsafe(16);
var buf5 = Buffer.allocUnsafeSlow(16);
var buf6 = Buffer.from([1, 2, 4, 7]);
var buf7 = Buffer.from(new ArrayBuffer(16), 4, 8);
var buf8 = Buffer.from(buf1);
var buf9 = Buffer.from('foo');

console.log(buf1);
console.log(buf2);
console.log(buf3);
console.log(buf4);
console.log(buf5);
console.log(buf6);
console.log(buf7);
console.log(buf8);
console.log(buf9);

console.log(buf1[0]);
buf1[0] = 16;
console.log(buf1[0]);

for (byte of buf9) {
    console.log(byte);
}
for ([index, byte] of buf9.entries()) {
    console.log(index + ': ' + byte);
}
for (index of buf9.keys()) {
    console.log(index);
}
for (byte of buf9.values()) {
    console.log(byte);
}

console.log(buf9.length);

console.log(Buffer.isBuffer({}));
console.log(Buffer.isBuffer(buf9));

console.log(buf1.equals(buf1));
console.log(buf1.equals(buf9));

console.log(buf1.toJSON());

実行結果

C:\work\node>node buffer.js
<Buffer 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01>
<Buffer 66 6f 6f 66 6f 6f 66 6f 6f 66 6f 6f 66 6f 6f 66>
<Buffer 66 6f 6f 66 6f 6f 66 6f 6f 66 6f 6f 66 6f 6f 66 66 6f 6f 66 6f 6f 66 6f 6f 66 6f 6f 66 6f 6f 66>
<Buffer 12 00 00 00 00 00 00 00 f2 ff ff ff 00 00 00 00>
<Buffer e0 ef bb 68 01 00 00 00 00 00 00 00 00 00 00 00>
<Buffer 01 02 04 07>
<Buffer 00 00 00 00 00 00 00 00>
<Buffer 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01>
<Buffer 66 6f 6f>
1
16
102
111
111
0: 102
1: 111
2: 111
0
1
2
102
111
111
3
false
true
true
false
{ type: 'Buffer',
  data: [ 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] }

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-Node.js