我在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
进行了二进制编码。
我也试过ascii,但后来我得到了一个不同但同样错误的结果。
答案 0 :(得分:7)
'binary'
编码是'latin1'
的别名,您在阅读非字符数据时显然不需要。
如果您想要原始数据,don't specify an encoding at all(或提供null
)*。您将获得Buffer
而不是字符串,然后您需要直接使用该字符串,而不是使用toString
。
*(某些API [例如fs.watch
]也接受'buffer'
,但它不在the list of encodings而readFileSync
没有说明。[谢谢{{3提供列表链接。])
答案 1 :(得分:5)
只是为了添加更多信息,发生这种情况的原因是因为您将字符串传递给stdout.write()
,在写入之前将其隐式转换回Buffer
,以及你在Node.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()
。