微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

偏移量在DataView的边界之外,调试器显示它在边界之内

如何解决偏移量在DataView的边界之外,调试器显示它在边界之内

我收到以下代码错误Offset is outside the bounds of the DataView

let data = [...] // some array of Int16
let buf = new ArrayBuffer(data.length);
let dataView = new DataView(buf);

data.forEach((b,i) => {
   dataView.setInt16(i,b);
});

这是Chrome中的调试视图

enter image description here

您会看到i47999,我的DataView的缓冲区大小是48000。我在这里想念什么?

解决方法

这是因为Int16Array每个元素有2个字节。因此,其.length的大小将比其缓冲区的实际大小小两倍,而应使用其.byteLength来创建相同大小的新ArrayBuffer。
另外,设置一个int16实际上将一次设置两个字节。

因此,在某个时候,您的循环将尝试设置一个不存在的字节,并将抛出该错误。

但这还不是您的代码的全部。由于forEach()的迭代值i是基于TypedArray的.length值的,因此您还需要将其乘以TypedArray每个元素的字节数,以在{{1 }}。

DataView.setInt16

现在,我不确定您要使用此代码段做什么,但是要复制您的TypedArray,则必须检查计算机的字节序,然后使用{ {1}},但您也可以简单地这样做:

const data = new Int16Array( [ 0xFFFF,0xFF00,0x00FF,0x000 ] );

console.log( "length:",data.length );
console.log( "byteLength:",data.byteLength );

const buf = new ArrayBuffer(data.byteLength);
const dataView = new DataView(buf);

data.forEach( (b,i) => {
  dataView.setInt16( i * data.BYTES_PER_ELEMENT,b );
} );
console.log( new Int16Array( buf ) );
// -1,255,-256,0

如果您希望从小字节序转换为大字节序,那么还可以通过首先检查计算机的字节序并在必要时使用DataView.setInt16( byteOffset,value,littleEndian )来交换值,从而使其比使用DataView更快。

const data = new Int16Array( [ 0xFFFF,0x000 ] );
const buf = data.buffer.slice();

// ensure they are not the same ArrayBuffer
data.fill( 0 );
console.log( "data: ",data ); // 0,0
console.log( "copy:",new Int16Array( buf ) );
// -1,256,0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。