Node.jsのバイナリデータの読み取りに問題があります。これが私がすることです:
$ cat test.js
var fs = require('fs'),
binary = fs.readFileSync('./binary', 'binary').toString('binary');
process.stdout.write(binary.substring(0, 48));
$ xxd binary
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 0008 0000 0000 0000 ..>.............
00000020: 4000 0000 0000 0000 10a0 0000 0000 0000 @...............
$ node test.js | xxd
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 0008 0000 0000 0000 ..>.............
00000020: 4000 0000 0000 0000 10c2 a000 0000 0000 @...............
00000030: 00 .
$
ノードで読み取るときに、インデックス0x29に0xc2バイトが挿入されることに注意してください。何故ですか? readFileSync
とtoString
の両方にバイナリエンコーディングを指定しました。私もアスキーを試しましたが、違う間違った結果になります。
'binary'
エンコーディングは'latin1'
のエイリアスです。これは、文字以外のデータを読み取る場合には明らかに望ましくありません。
生データが必要な場合は、 エンコードを指定しないでください (またはnull
)*を指定します。文字列の代わりに Buffer
を取得します。これは、toString
を使用するのではなく、直接使用することになります。
*(一部のAPI [fs.watch
]なども'buffer'
を受け入れますが、 エンコーディングのリスト には含まれておらず、readFileSync
はそうではありません。 Patrick リストリンクを提供してくれてありがとう。])
さらに情報を追加するために、これが発生する理由は、文字列をstdout.write()
に渡しているためです。これは、書き込まれる前に暗黙的にBuffer
に変換され、ノードでそれを行うときに発生します。 js REPLバイナリファイルの0x28の位置にこの特定のサブストリングがある場合、説明した動作が得られます。
_> new Buffer('\u0010\u00a0')
<Buffer 10 c2 a0>
_
@ T.J.Crowderが正しく提案したように、スクリプトを修正する方法は次のとおりです。
_var fs = require('fs'),
binary = fs.readFileSync('./binary');
process.stdout.write(binary.slice(0, 48));
_
また、Buffer#slice()
の代わりに String#substring()
を使用します。