2016-06-21 58 views
0

我想创建一个ArrayBuffer对象的视图,以JSON化它。你如何决定使用哪种类型的数组?

var data = { data: new Uint8Array(arrayBuffer) } 
var json = JSON.stringify(data) 

看来,ArrayBuffer的大小并不重要,即使是最小Uint8Array。我没有得到任何RangeError到目前为止:)如果是这样,我该如何决定使用哪种类型的数组?

+0

您根据存储在缓冲区中的数据,或者更好地说,根据您对该数据的解释来决定。 –

+3

另一个'Uint8Array'不是8位数组,它是一个无符号8位整数数组。它可以有任何长度。由同一个'ArrayBuffer'创建的'Uint8Array'与'Uint16Array'相比,将会增长两倍,因为'ArrayBuffer'中的每个字节都将被放置为'Uint8Array'的一个元素,而对于'Uint16Array'每对字节将“变成”数组中的一个元素。 –

+0

@SergiuParaschiv你应该发布这个答案。你完美地解释了它。 –

回答

3

您根据存储在缓冲区中的数据,或者更好地说,根据您对该数据的解释来决定。

另外一个Uint8Array不是一个8位数组,它是一个无符号8位整数数组。它可以有任何长度。 A Uint8Array从相同的ArrayBuffer创建为​​将是两倍长,因为ArrayBuffer中的每个字节将被“放置”为Uint8Array的一个元素,而对于​​,每对字节将“成为“阵列中的一个元素。

如果我们尝试用二进制来思考,会发生什么的一个很好的解释。尝试运行此:

var buffer = new ArrayBuffer(2); 
var uint8View = new Uint8Array(buffer); 
var uint16View = new Uint16Array(buffer); 

uint8View[0] = 2; 
uint8View[1] = 1; 

console.log(uint8View[0].toString(2)); 
console.log(uint8View[1].toString(2)); 
console.log(uint16View[0].toString(2)); 

输出将是

10 
1 
100000010 

因为显示为二进制一个无符号的8位整数,2是00000010和1是00000001(toString条前导零)。

Uint8Array表示一个字节数组。正如我所说的,一个元素是一个无符号的8位整数。我们只是推了两个字节。

在内存中,这两个字节并排存储为00000001 00000010(二进制形式再次用于使事情更清晰)。

现在,当你在它会含有相同的字节数相同的缓冲初始化​​,而是因为一个元素是一个16位无符号整数(两个字节),当您访问uint16View[0]它会采取先字节并将它们还给你。所以0000000100000010,这是100000010没有前导零。

如果您将此数据解释为基数10(十进制)整数,那么您将知道它是基于10(258)的0000000100000010

Uint8Array也没有​​本身存储任何数据。它们只是在ArrayBuffer中访问字节的不同方式。

如何一个选择哪一个使用?它不是基于偏好,而是基于基础数据。 ArrayBuffer用于从某些外部源(网络套接字也许)接收到一些二进制数据,并且知道数据表示的内容。它可能是一个无符号的8位整数列表,或者是一个有符号的16位整数列表,或者是一个混合列表,您知道第一个元素是一个8位整数,而下一个是16位整数。然后,您可以使用DataView从中读取输入的项目。 如果你不知道数据代表什么,你不能选择使用什么。

+0

令人印象深刻的答案! +1为彻底。 – sawa

+0

如果我不打算使用DataView,并且只需创建ArrayBuffer视图以便JSONify并通过AJAX请求发送它仅反序列化它,那么数据格式并不重要,我猜?除了Uint8Array更快? – sawa

+1

你根本看不出有什么不同。所有这些都只是“意见” - 解释数据的方式。数据本身存储在缓冲区中。 –