Node.js Buffer モジュール

Node.js 組み込みモジュール


Buffer は Node.js においてバイナリデータストリームを処理するためのクラスです。コンピュータでは、すべてのデータは最終的にバイナリ形式で保存・転送されます。Buffer は、これらの生のバイナリデータを Node.js で効率的に処理する方法を提供します。

Buffer は、生のバイナリデータを格納するための専用の固定サイズの「コンテナ」と考えることができます。JavaScript の通常の配列とは異なり、Buffer は固定サイズのメモリブロックを割り当てるため、大量のバイナリデータを処理する際により効率的です。


なぜ Buffer が必要なのか?

Web 開発では、さまざまなバイナリデータを頻繁に扱う必要があります。例えば:

  • ファイルの読み書き操作
  • ネットワーク通信におけるデータ転送
  • 画像処理
  • 暗号化・復号化操作

JavaScript は当初、ブラウザでの DOM 操作を主目的として設計されており、バイナリデータの処理能力は限られていました。Node.js はサーバーサイドランタイムとして、より強力なバイナリデータ処理能力を必要とします。これが Buffer モジュールが存在する理由です。


Buffer の作成

Node.js で Buffer を作成する方法はいくつかあります:

1. Buffer.alloc() を使用する

例

// 長さ 10 バイトの Buffer を作成し、0 で埋める
const buf1 = Buffer.alloc(10);
console.log(buf1); // <Buffer 00 00 00 00 00 00 00 00 00 00>

2. Buffer.allocUnsafe() を使用する

例

// 長さ 10 バイトの Buffer を作成するが、内容は初期化しない
// 古いデータが含まれる可能性があるため、高速だが安全性は低い
const buf2 = Buffer.allocUnsafe(10);
console.log(buf2); // <Buffer の内容は不定>

3. 配列から作成する

例

// 配列から Buffer を作成する
const buf3 = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
console.log(buf3); // <Buffer 62 75 66 66 65 72>

4. 文字列から作成する

例

// 文字列から Buffer を作成する
const buf4 = Buffer.from('Hello Node.js');
console.log(buf4); // <Buffer 48 65 6c 6c 6f 20 4e 6f 64 65 2e 6a 73>

Buffer のよく使うメソッド

データの書き込み

例

const buf = Buffer.alloc(5);

// 文字列を書き込む
buf.write('Hello');
console.log(buf); // <Buffer 48 65 6c 6c 6f>

// 書き込み時にエンコーディングを指定する
const buf2 = Buffer.alloc(10);
buf2.write('你好', 'utf8');
console.log(buf2); // <Buffer e4 bd a0 e5 a5 bd 00 00 00 00>

データの読み取り

例

const buf = Buffer.from('Hello World');

// 文字列として読み取る
console.log(buf.toString()); // Hello World

// 一部の内容を読み取る
console.log(buf.toString('utf8', 0, 5)); // Hello

Buffer のコピー

例

const buf1 = Buffer.from('Hello');
const buf2 = Buffer.from('World');
const buf3 = Buffer.alloc(10);

buf1.copy(buf3, 0); // buf1 を buf3 の先頭にコピーする
buf2.copy(buf3, 5); // buf2 を buf3 の5バイト目から始まる位置にコピーする

console.log(buf3.toString()); // HelloWorld

Buffer の連結

例

const buf1 = Buffer.from('Hello');
const buf2 = Buffer.from(' ');
const buf3 = Buffer.from('World');

const result = Buffer.concat([buf1, buf2, buf3]);
console.log(result.toString()); // Hello World

Buffer と文字列

Buffer と文字列は相互に変換できますが、エンコーディングに注意する必要があります。一般的なエンコーディングは次のとおりです:

  • 'utf8' (デフォルト)
  • 'ascii'
  • 'base64'
  • 'hex'

例

例

// 文字列を Buffer に変換する
const str = 'Hello Buffer';
const buf = Buffer.from(str);

// Buffer を文字列に変換する
console.log(buf.toString()); // Hello Buffer

// 異なるエンコーディングを使用する
console.log(buf.toString('hex')); // 48656c6c6f20427566666572
console.log(buf.toString('base64')); // SGVsbG8gQnVmZmVy

Buffer の実際の応用

1. ファイル操作

例

const fs = require('fs');

// ファイルを読み込んで Buffer にする
fs.readFile('example.txt', (err, data) => {
  if (err) throw err;
  console.log(data); // <Buffer ...>
  console.log(data.toString()); // ファイルの内容
});

// Buffer をファイルに書き込む
const content = Buffer.from('Hello File System');
fs.writeFile('output.txt', content, (err) => {
  if (err) throw err;
  console.log('文件已保存');
});

2. ネットワーク通信

例

const http = require('http');

http.createServer((req, res) => {
  const chunks = [];
 
  req.on('data', (chunk) => {
    chunks.push(chunk); // データチャンクを収集する
  });
 
  req.on('end', () => {
    const body = Buffer.concat(chunks); // すべてのデータチャンクを結合する
    console.log(`受信したデータ: ${body.toString()}`);
    res.end('数据已接收');
  });
}).listen(3000);

3. 画像処理

例

const fs = require('fs');
const sharp = require('sharp');

// 画像を読み込んで Buffer にする
fs.readFile('input.jpg', (err, data) => {
  if (err) throw err;
 
  // sharp を使用して Buffer 内の画像データを処理する
  sharp(data)
    .resize(200, 200)
    .toBuffer()
    .then(outputBuffer => {
      // 処理後の Buffer をファイルに書き込む
      fs.writeFile('output.jpg', outputBuffer, err => {
        if (err) throw err;
        console.log('图片处理完成');
      });
    });
});

注意事項

  1. メモリ管理:Buffer はメモリを直接操作するため、大きな Buffer を割り当てるとアプリケーションのパフォーマンスに影響します。

  2. 安全性:Buffer.allocUnsafe()機密データが含まれる可能性があるため、使用時には注意が必要です。

  3. エンコーディングの一貫性:Buffer と文字列を変換する際は、同じエンコーディングを使用するようにしてください。

  4. バージョンの違い:Node.js の古いバージョン (v5.x 以前) の Buffer API は新しいバージョンとは異なります。最新の API を使用することをお勧めします。

  5. パフォーマンスの考慮:大量のデータ処理において、Buffer を適切に使用するとパフォーマンスが大幅に向上します。

Buffer は Node.js でバイナリデータを処理する中核モジュールです。その動作原理と使い方を理解することは、効率的で信頼性の高い Node.js アプリケーションを開発するために不可欠です。


Bufferモジュールのメソッドとプロパティ一覧

BufferNode.js でバイナリデータを処理するための中核モジュールです。以下は Buffer モジュールの主なメソッドとプロパティです:

Buffer クラスのプロパティ

プロパティ/メソッド 説明 導入バージョン
Buffer.poolSize 事前に割り当てられた内部 Buffer インスタンスのサイズ(バイト)。変更可能 0.11.3
Buffer.from() 文字列、配列、またはバッファから新しい Buffer を作成する 5.10.0
Buffer.alloc() 指定サイズの初期化済み Buffer を作成する 5.10.0
Buffer.allocUnsafe() 指定サイズの未初期化 Buffer を作成する(高速だが安全ではない) 5.10.0
Buffer.allocUnsafeSlow() 未初期化 Buffer を作成する(共有メモリプールを使用しない) 5.12.0
Buffer.isBuffer() オブジェクトが Buffer かどうかを検査する 0.1.101
Buffer.isEncoding() エンコーディングが有効かどうかを検査する 0.9.1
Buffer.concat() Buffer の配列を結合する 0.7.11
Buffer.byteLength() 文字列のバイト長を返す 0.1.90
Buffer.compare() 2つの Buffer を比較する 0.11.13

Buffer インスタンスのメソッド

メソッド 説明 導入バージョン
buf.length Buffer のバイト長 0.1.90
buf.write() Buffer に文字列を書き込む 0.1.90
buf.toString() Buffer を文字列にデコードする 0.1.90
buf.toJSON() Buffer の JSON 表現を返す 0.9.2
buf.equals() 2つの Buffer が等しいかどうかを比較する 0.11.13
buf.compare() Buffer を比較してソート順序を返す 0.11.13
buf.copy() Buffer データをコピーする 0.1.90
buf.slice() Buffer の部分ビューを作成する 0.3.0
buf.includes() Buffer に値が含まれているかどうかを検査する 5.3.0
buf.indexOf() 値が最初に出現する位置を返す 1.5.0
buf.lastIndexOf() 値が最後に出現する位置を返す 6.0.0
buf.fill() 指定した値で Buffer を埋める 0.5.0
buf.readUIntLE() 符号なしリトルエンディアン整数を読み取る 0.5.5
buf.readUIntBE() 符号なしビッグエンディアン整数を読み取る 0.5.5
buf.readIntLE() 符号付きリトルエンディアン整数を読み取る 0.11.15
buf.readIntBE() 符号付きビッグエンディアン整数を読み取る 0.11.15
buf.readDoubleBE() ビッグエンディアン64ビット倍精度浮動小数点数を読み取る 0.11.15
buf.readDoubleLE() リトルエンディアン64ビット倍精度浮動小数点数を読み取る 0.11.15
buf.readFloatBE() ビッグエンディアン32ビット浮動小数点数を読み取る 0.11.15
buf.readFloatLE() リトルエンディアン32ビット浮動小数点数を読み取る 0.11.15
buf.writeUIntLE() 符号なしリトルエンディアン整数を書き込む 0.5.5
buf.writeUIntBE() 符号なしビッグエンディアン整数を書き込む 0.5.5
buf.writeIntLE() 符号付きリトルエンディアン整数を書き込む 0.11.15
buf.writeIntBE() 符号付きビッグエンディアン整数を書き込む 0.11.15
buf.writeDoubleBE() ビッグエンディアン64ビット倍精度浮動小数点数を書き込む 0.11.15
buf.writeDoubleLE() リトルエンディアン64ビット倍精度浮動小数点数を書き込む 0.11.15
buf.writeFloatBE() ビッグエンディアン32ビット浮動小数点数を書き込む 0.11.15
buf.writeFloatLE() リトルエンディアン32ビット浮動小数点数を書き込む 0.11.15
buf.swap16() 16ビットのバイト順を交換する 5.10.0
buf.swap32() 32ビットのバイト順を交換する 5.10.0
buf.swap64() 64ビットのバイト順を交換する 6.3.0
buf.keys() Bufferキーのイテレータを作成する 1.1.0
buf.values() Buffer値のイテレータを作成する 1.1.0
buf.entries() [index, byte] イテレータを作成する 1.1.0

エンコーディングの種類

Bufferがサポートするエンコーディングタイプ:

エンコーディング 説明
utf8 マルチバイトUnicode文字
utf16le 2または4バイトのUnicode文字
latin1 ISO-8859-1
ascii 7ビットASCIIデータのみ
base64 Base64エンコーディング
base64url URLセーフなBase64エンコーディング
hex 16進数エンコーディング
ucs2 utf16leのエイリアス
binary latin1のエイリアス(非推奨)

例

// Bufferを作成
const buf1 = Buffer.alloc(10); // ゼロ初期化されたBufferを作成
const buf2 = Buffer.from('hello'); // 文字列から作成
const buf3 = Buffer.from([1, 2, 3]); // 配列から作成

// 書き込みと読み取り
buf1.write('Node.js');
console.log(buf1.toString('utf8', 0, 6)); // 'Node.js'

// Bufferを比較
const bufA = Buffer.from('A');
const bufB = Buffer.from('B');
console.log(bufA.compare(bufB)); // -1

// Bufferを結合
const concatBuf = Buffer.concat([bufA, bufB]);

Node.js組み込みモジュール

その他の拡張