为何这段JavaScript代码会出现字节序不匹配问题?
跨浏览器二进制数据读写的字节序问题排查
问题场景
0x00000101(十进制257)以Uint32类型存储到二进制文件后,对其是否为小端字节序表示存疑。使用DataView.getUint32读取时结果异常,遂编写浏览器代码复现Node.js中遇到的问题。
复现代码与输出
let data = new Uint8Array([0,0,1,1]); let view = new DataView(data.buffer); writeLog(`reading little endian data (${data.join()}): ${view.getUint32(0, true)}`); writeLog(`reading big endian data (${data.join()}): ${view.getUint32(0, false)}`);
输出结果:
reading little endian data (0,0,1,1): 16842752 reading big endian data (0,0,1,1): 257
疑问点
- 我忽略了什么细节?
DataView.getUint32与setUint32的字节序处理是否存在差异?
问题根源
经排查,问题源于自定义类构造函数中对字节序标志的错误实现:
错误实现:
constructor(littleEndian?:boolean) { if (littleEndian === undefined) { this.#littleEndian = isMachineLittleEndian; } }
这段代码仅处理了littleEndian为undefined的情况,当传入非undefined值时,this.#littleEndian未被赋值,导致后续调用setUint32时使用了错误的字节序,与getUint32传入true指定的小端模式不匹配,最终引发读取结果异常。
正确实现:
constructor(littleEndian?:boolean) { if (littleEndian === undefined) { this.#littleEndian = isMachineLittleEndian; } else { this.#littleEndian = !!littleEndian; } }
此案例说明,当向setUint32传入undefined、向getUint32传入true时,若字节序标志未正确初始化,会导致二进制数据读写的字节序不匹配问题。
内容的提问来源于stack exchange,提问作者Kote Isaev
相关产品推荐
相关产品推荐

