Endianness安全复制二进制数据
我想用ArrayBuffer处理二进制数据。如果原始ArrayBuffer如下所示:Endianness安全复制二进制数据
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方法没有预谋,所以我做到了我自己。这不是问题,但考虑到endianness真的让我发疯。
前5个字节的数据是由我制作的,所以我可以手动设置字节顺序,但原始数据来自外部,所以数据可能是Little Endian和Big Endian。
我为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?或者我应该忘记排序?任何建议将非常感激。
对于因为他们没有字节序没关系字节,但如果你不是一个字节的更宽的数据(16位/ 32位等),你必须预先知道字节序,因为没有办法检测原始的字尾(你可以根据数据做一些猜测,但是...)。
在大多数情况下,字节流是在所谓的网络秩序基本上是大端,什么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
}
结果然后可以使用所述小端标志的各种方法的数据视图中。
请注意,这适用于数据流,并不一定是服务器的CPU架构/永久性(小端服务器仍可以(并且很可能)以大端/网络顺序发送数据)。
您尚未显示服务器用于从其接收的二进制数据中读取的代码? – Bergi