質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

5221閲覧

fs.createReadStreamで文字コードをshift-jisからutf-8に変換して出力したい

hiroaki_

総合スコア6

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2021/12/03 06:27

下記コードです。
fs.createReadStreamでsample.tsvを読み込んで出力しているのですが、tsvを出力した際に文字化けしてしまっています。
そのためiconv-liteを使用して文字コード変換してから出力をしたいと考えているのですが、下記コードで実行するとうまくいきません。

node script.jsで実行しても空白の出力で返ってきてしまう状態です。
良い解決方法がありましたらご教授いただけますと幸いです。

javascript

1const fs = require('fs') 2const csv = require('./node_modules/csv') 3const iconv = require('./node_modules/iconv-lite'); 4 5const parser = csv.parse({ trim: true }, function (err, data) { 6 const buf = new Buffer.from(data, 'binary'); 7 const retStr = iconv.decode(buf, "Shift_JIS"); 8 console.log(retStr); 9}); 10fs.createReadStream(__dirname + '/files/sample.tsv').pipe(parser);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

優先順位が間違っています。
質問文のコードではファイル開いて真っ先にCSVの解析にかけていますが
真っ先にiconv.decodeでShift-JISをUTF-8にするすべきです。

そうでなきゃダメ文字等で勝手にエスケープとして使われる\記号が混入することになるので、どうなるかわかりません。

またNode.jsで実装されているStreamは難解なので出来れば避けましょう。
fs.readFileSync等で超巨大なファイルを読んでメモリが枯渇してエラー吐いて落ちるパターンがありますが
Streamを使って超巨大なファイルを先頭から少しずつ読み、
少量のバイト文字列を別の関数に流し込んでいくというバケツリレー作戦を取ることで解決する手法です。

その超巨大なファイルでもなければStreamを使う意味がありません。
Buffer型として一気に読み込んでしまったほうが楽です。
これを踏まえてこのようにしてしまってはどうでしょうか?

csvライブラリのサイトを見たら
パースしたいだけならcsv-parser使ってどうぞみたいな表記とともに同期処理の手順が例としてあったのでそちらに変更しています。

bash

1$ npm install csv-parser

js

1const fs = require('fs'); 2const {parse} = require('csv-parse/sync'); 3// 現在のディレクトリを指す.始まりで無い限り、勝手にnode_modulesを探すので不要 4const iconv = require('iconv-lite'); 5 6const bin = fs.readFileSync(__dirname + '/files/sample.tsv'); 7// Shift-JISといっても候補が色々あるんだよなぁ、CP932とか……まぁ色々試してみて 8const utf8 = iconv.decode(bin, "Shift_JIS"); 9// TSVなら区切り文字\t指定で行けるんかね? 10const tsv = parse(utf8, {delimiter: "\t"});

未確認ですがこれで先に進めると思います
頑張ってください

投稿2021/12/04 07:15

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiroaki_

2021/12/05 06:39

ご回答ありがとうございます! streamを使わずに、fs.readFileSyncを使用することでうまくいきました! iconv-liteでの変換も問題ありませんでした、本当に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問