Node.jsãšããã°ãUTF-8ã®ãšã³ã³ãŒãã£ã³ã°ãåºæ¬ã§ãShift_JISãEUC-JPãªã©ãæ±ãå Žåã«ã¯ã©ããããã ããïŒãšæã£ãŠ
ããã®ã§ããããiconv-liteããšããã¢ãžã¥ãŒã«ã䜿çšããã®ãããã¿ããã§ãã
GitHub - ashtuchkin/iconv-lite: Convert character encodings in pure javascript.
ãããèŠããšãå€æè¡šãå®è£
ããŠããæããªãã§ãããããšâŠã
https://github.com/ashtuchkin/iconv-lite/tree/v0.4.19/encodings
ãµããŒãããŠãããšã³ã³ãŒãã£ã³ã°ã¯ããã¡ãã
Supported Encodings · ashtuchkin/iconv-lite Wiki · GitHub
ãšããããã䜿ã£ãŠãã£ãŠã¿ãŸãããã
ç°å¢
確èªæã®ç°å¢ã¯ã以äžã®éãã
$ node -v v9.5.0 $ npm -v 5.6.0
æºå
ããã¥ã¡ã³ãã«æ²¿ã£ãŠãnpmã§ã€ã³ã¹ããŒã«ã
$ npm install --save iconv-lite
package.jsonã§ã®äŸåé¢ä¿ã¯ããã®ããã«ãªããŸããã
"dependencies": { "iconv-lite": "^0.4.19" },
åäœèªäœã¯ããã¹ãã³ãŒãã§ç¢ºèªããŸãããã
ä»åã¯ãJestã䜿ãããšã«ããŸããã
$ npm install --save-dev jest
package.jsonã§ã®äŸåé¢ä¿ã¯ããã®ããã«ã
"devDependencies": { "jest": "^22.2.2" }
ãnpm run testãã§ãJestãèµ·åããããã«ããŠãããŸããã
"scripts": { "test": "jest" },
ãã¹ãããŒã¿ãçšæããŠãããŸãããããã¡ã€ã«ã§ãiconvã䜿ã£ãŠç°¡åã«äœããŸãã
$ echo -n "ããããã" > data/utf8.txt $ iconv -f UTF-8 -t Windows-31J -o data/sjis.txt data/utf8.txt $ iconv -f UTF-8 -t EUCJP-MS -o data/eucjp.txt data/utf8.txt
ãã¡ãã䜿ã£ãŠç¢ºèªããŠãããŸãããã
確èª
ãŸãã¯ãrequireããã
test/iconv-lite.test.js
const fs = require("fs"); const iconv = require("iconv-lite");
fsã¢ãžã¥ãŒã«ã¯ãã¡ã€ã«èªã¿èŸŒã¿ã®ããã§ãä»åã®äž»åœ¹ã¯iconv-liteã§ãã
decode
ãšãããããUTF-8ã®ãã¡ã€ã«ã¯æšæºæ©èœã§èªãã§ã¿ãŸãã
test("read standard utf8", done => { fs.readFile("data/utf8.txt", "utf-8", (err, data) => { expect(data).toEqual("ããããã"); done(); }); });
ããããiconv-liteã§ã
test("read utf8, using iconv-lite", done => { fs.readFile("data/utf8.txt", (err, data) => { const stringData = iconv.decode(data, "utf-8"); expect(stringData).toEqual("ããããã"); done(); }); });
iconv#decodeã䜿ã£ãŠãBufferãå€æããŸãããšã
const stringData = iconv.decode(data, "utf-8");
Shift_JISãšEUC-JPã«ã€ããŠããåãã
test("read shift-jis, using iconv-lite", done => { fs.readFile("data/sjis.txt", (err, data) => { const stringData = iconv.decode(data, "windows-31j"); expect(stringData).toEqual("ããããã"); done(); }); }); test("read euc-jp, using iconv-lite", done => { fs.readFile("data/eucjp.txt", (err, data) => { const stringData = iconv.decode(data, "eucjp"); expect(stringData).toEqual("ããããã"); done(); }); });
ãã®ããããèŠããšããWindows-31JãããCP932ãã¯ãShift_JISãã®ãšã€ãªã¢ã¹ã£ãœãã§ãã
https://github.com/ashtuchkin/iconv-lite/blob/v0.4.19/encodings/dbcs-data.js#L41-L56
EUC-JPã¯ãã²ãšã€ã ãã ã£ããã
https://github.com/ashtuchkin/iconv-lite/blob/v0.4.19/encodings/dbcs-data.js#L58-L62
encode
ä»åºŠã¯ãencodeãåçŽã«ãStringã«å¯ŸããŠencodeããŠã¿ãŸãã
ãŸãã¯ãæšæºAPIã®ç¯å²ã§ã
test("encode standard utf-8", () => { const data = "ããããã"; const buffer = Buffer.from(data, "utf-8"); expect(buffer).toEqual(Buffer.from([0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a])); });
iconv-liteã䜿ã£ãŠãUTF-8ãShift_JISãEUC-JPã§encodeã
test("encode utf-8, using iconv-lite", () => { const data = "ããããã"; const buffer = iconv.encode(data, "utf-8"); expect(buffer).toEqual(Buffer.from([0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84, 0xe3, 0x81, 0x86, 0xe3, 0x81, 0x88, 0xe3, 0x81, 0x8a])); }); test("encode shift-jis, using iconv-lite", () => { const data = "ããããã"; const buffer = iconv.encode(data, "windows-31j"); expect(buffer).toEqual(Buffer.from([0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4, 0x82, 0xa6, 0x82, 0xa8])); }); test("encode euc-jp, using iconv-lite", () => { const data = "ããããã"; const buffer = iconv.encode(data, "eucjp"); expect(buffer).toEqual(Buffer.from([0xa4, 0xa2, 0xa4, 0xa4, 0xa4, 0xa6, 0xa4, 0xa8, 0xa4, 0xaa])); });
ãã¡ãã®å Žåã¯ãiconv#encodeã䜿çšããŠStringãBufferã«å€æããŸãããšã
const buffer = iconv.encode(data, "utf-8");
Streaming
ãããŸã§ã¯ãiconv#encodeïŒdecodeãšStringãšBufferã®å€æããã£ãŠããŸããããStreming APIãšãããã®ãããããã§ãã
ããã«ãããstream.ReadableãšåãããŠäœ¿ãã¿ããã§ããã
Stream | Node.js v9.11.2 Documentation
fs#createReadStreamã«å¯ŸããŠãpipeã§iconv#decodeStreamãæå®ã
test("read utf-8 stream, using iconv-lite", done => { fs .createReadStream("data/utf8.txt") .pipe(iconv.decodeStream("utf-8")) .collect((err, data) => { expect(data).toEqual("ããããã"); done(); }); });
collectã£ãŠstream.Readableã«ãèŒã£ãŠããªããŠããªãã ããïŒãšæã£ãã®ã§ãããiconv-liteã§äœã£ãŠãããã®ã®ããã§ãã
https://github.com/ashtuchkin/iconv-lite/blob/v0.4.19/lib/streams.js#L65-L73
https://github.com/ashtuchkin/iconv-lite/blob/v0.4.19/lib/streams.js#L112-L120
stream.Readableã®ã€ãã³ãã䜿ããªãããããªæãã§ããããã
test("read utf-8 stream and event, using iconv-lite", done => { const stream = fs .createReadStream("data/utf8.txt") .pipe(iconv.decodeStream("utf-8")); stream.on("data", chunk => expect(chunk).toEqual("ããããã")); stream.on("end", () => done()); });
stream.Readableãããstream.Writableã«ãšã³ã³ãŒãã£ã³ã°ãå€æããŠæµã蟌ã¿ã
test("write shift-jis stream, using iconv-lite", done => { const stream = fs .createReadStream("data/eucjp.txt") .pipe(iconv.decodeStream("eucjp")) .pipe(iconv.encodeStream("windows-31j")) .pipe(fs.createWriteStream("data/sjis-iconv-lite.txt")); stream.on("finish", () => { fs.readFile("data/sjis-iconv-lite.txt", (err, data) => { const stringData = iconv.decode(data, "windows-31j"); expect(stringData).toEqual("ããããã"); done(); }); }); });
ãšãããããåºæ¬çãªäœ¿ãæ¹ãšBufferãStreamã®APIã«ã¡ããã£ãšè§Šãããšããã§ãä»åã¯ãããŸãã§ãã