我试图用ArrayBuffer操作二进制数据。如果原始ArrayBuffer如下所示:
var buffer = new ArrayBuffer(40);
var dv = new DataView(buffer);
var num = 0;
for(var i = 0; i < 40; i+=2) {
dv.setUint16(i, num++);
}ArrayBuffer的长度为20 Uint16Array。我想要额外的二进制数据,而不是附加数据。假设我想像这样在5个字节的Uint8前面加上:
ArrayBuffer[0] = 10;
ArrayBuffer[1] = 20;
ArrayBuffer[2] = 30;
ArrayBuffer[3] = 40;
ArrayBuffer[4] = 50;
ArrayBuffer[5 ~ 25] = Original Data据我所知,在ArrayBuffer中没有前置的like方法,所以我自己做了。这不重要,但考虑到痴情真的让我发疯了。
前5个字节的数据是由我产生的,所以我可以手动设置endianness,但是原始数据来自外部,所以数据可以是Little Endian和Big。
我正在为Node.js和Web制作某种二进制数据模块,基本用法是使用该模块从Web浏览器中预置额外的二进制数据,浏览器将其发送到服务器,然后服务器也从该模块读取这些二进制数据,然后分割成预置和原始数据。
但问题是,如果浏览器,我指的是使用小终端的客户端计算机,而服务器使用大端,原始数据可能无法正确读取,因为它们具有不同的特性。
我将原始数据附加到像这样的新二进制数据中。新的二进制数据在0~5字节时有不同的5字节数据。所以我必须在5个字节偏移后写。
// write rest of data
var newBuffer = new ArrayBuffer(5 + origBuffer.byteLength);
var ndv = new DataView(newBuffer);
var dv = new DataView(origBuffer);
for(var i = 0; i < origBuffer.byteLength; i++) {
var offset = 5 + i;
ndv.setUint8(offset, dv.getUint8(i));
}在我的本地机器上进行测试是可以的,因为服务器和客户端都使用相同的cpu,但是在现实生活中,如果它们有不同的特性,这个模块将不能正常工作。
是否有一种使用ArrayBuffer & DataView复制二进制数据的安全方法?还是我应该忘了她的恩典?任何建议都会很感激的。
发布于 2016-11-30 23:39:12
对于字节来说,这并不重要,因为它们没有endianess性,但是如果您获得的数据比字节(16/32位等)更宽,您就必须提前了解它,因为没有办法检测原始endianess (您可以根据数据进行一些猜测,但是.)。
在大多数情况下,字节流是按照所谓的网络顺序的,基本上是大端的,DataView默认的是什么。
但是,我建议在向客户端发送任何数据之前实现一个测试函数。例如,使用isLittleEndian()函数从客户端调用服务器,该函数触发服务器返回一个16位值,如0xff00。然后测试接收字节的顺序--类似于:
function isLittleEndian(callback) { // callback as request will be async
// get 0xff00 from server as 2 byte ArrayBuffer here somehow...
var test = new Uint8Array(arraybufferFromServer);
callback({isLittleEndian: !test[0]}); // will be 0x00ff as little-endian
}然后,可以使用各种方法的小endian标志将结果与DataView一起使用。
请注意,这适用于数据流,而不一定适用于服务器的CPU体系结构/endian(小端服务器仍然可以(也很可能)以大端/网络顺序发送数据)。
发布于 2016-11-24 14:15:42
由于您使用的不是具有索引访问的Uint16Array,而是DataView及其 method,因此endianness始终默认为大端。
https://stackoverflow.com/questions/40787793
复制相似问题