yamaday0u Blog Written by yamaday0u

【Node.js】iconv-liteで文字コードを変換しながらStreamを使う

Node.js

こんにちは、やまだゆうです。

先日、Node.jsのStream APIに関する記事を公開しました。

【Node.js】Stream APIを使ってデータを少しずつ処理してみよう | yamaday0u Blog

Stream APIは日本でよく使われているShift_JISという文字コードをサポートしていません。処理によってはShift_JISなどのStream APIのサポート外の文字コードを扱う必要があると思います。そこで活躍するのが「iconv-lite」というライブラリです。

この記事の内容

  1. iconv-liteとは
  2. iconv-liteを使ったStreamの処理サンプル

スポンサーリンク

iconv-liteとは

まず、iconv(アイコンブ)とはなんでしょうか?Wikipediaでは以下のように解説されています。

異なる文字コード間の相互変換を行う標準API。または、そのAPIに付属する文字コード変換ユーティリティプログラム。名前は「International Codeset Conversion Library」に由来する。

Wikipedia

iconv-liteはiconvのJavaScript向けのライブラリということになります。
なぜ「lite」という名前がつくかというと、もともとnode-iconvというライブラリが存在していて、それよりも軽量で処理速度が速いからみたいです。

Githubには速度の比較表が載っていて、node-iconvよりもエンコード/デコードの速度が3倍くらい速い結果が紹介されています。

ashtuchkin/iconv-lite

提供されているAPI

直感的と紹介されているように、シンプルで理解しやすいAPIが提供されています。

  • decode():デコード
  • encode():エンコード
  • decodeStream():Streamによるデコード
  • encodeStream():Streamによるエンコード

対応している文字コード

Node.jsのStream APIでサポートされている文字コードやShift_JISはもちろん、さまざまな文字コードをサポートしています。

Supported Encodings

iconv-liteを使ったStreamの処理サンプル

200 DegreesによるPixabayからの画像

これから紹介するプログラムはぼくのGithubで公開していますので、よければそちらもご覧ください。

stream-practice/iconv-practice

iconv-liteを使う準備をしましょう。

npm install iconv-lite

utf-8で作成したファイルを用意します。

こんにちは、テストです。
file --mime source.txt
# => source.txt: text/plain; charset=utf-8
const { createReadStream, createWriteStream } = require("fs");
const { pipeline } = require("stream/promises");

const readableStream = createReadStream("source.txt", "utf-8"); // utf-8でデコード
const writableStream = createWriteStream("destination.txt");

const { encodeStream } = require("iconv-lite");
const encodeToShiftJIS = encodeStream("Shift_JIS"); // Shift_JISでエンコード

const run = async () => {
  await pipeline(readableStream, encodeToShiftJIS, writableStream);
  console.log("finish!");
};

try {
  run();
} catch (error) {
  console.log(error);
}

source.txtファイルと同じディレクトリにdestination.txtファイルが作成されます。文字コードを確認すると以下のようになっています。

file --mime destination.txt
# => destination.txt: text/plain; charset=unknown-8bit

unkown-8bitはShift_JISのことです。

`charset=unknown-8bit`とは何か?

おまけ:Streamとの連携

上記のサンプルプログラムについて補足説明します。pipeline()は引数にReadStream、ReadWriteStream、WriteStreamを取ります。

サンプルプログラムでは、iconv-liteのencodeStream()の返り値をpipeline()の第2引数として渡しています。

iconv-liteのencodeStream()は以下のように定義されています。

export function encodeStream(encoding: string, options?: Options): NodeJS.ReadWriteStream;

返り値がNodeJS.ReadWriteStreamとなっているので、pipeline()の第2引数として渡すことができるというわけです。このように使用しているライブラリの定義まで理解すると、自分でコントロールして使えている感覚を得られるし面白いですよね!

スポンサーリンク

参考資料

yamaday0uを応援お願いします!あなたの1クリックが励みになります。
>> にほんブログ村