如何在Javascript中存储一个字节数组

问题描述 投票:56回答:4

我将在Javascript中存储一个大型的字节值数组(很可能超过一百万)。如果我使用一个普通的数字数组,那将需要8 MB,因为数字是以IEEE双数的形式存储的,但如果我可以以字节的形式存储,那就只有1 MB。

我想避免浪费那么多空间,原因很明显。有没有一种方法可以将字节存储为字节而不是双字节?浏览器兼容性对我来说不是问题,只要能在Chrome浏览器中使用就可以了。这是在HTML5中,如果这有区别的话。

javascript arrays html bytearray byte
4个回答
63
投票

通过使用 类型化数组的数组,你可以存储 此类:

  • Int8
  • Uint8
  • Int16
  • Uint16
  • Int32
  • Uint32
  • Float32
  • Float64

比如说。

​var array = new Uint8Array(100);
array[42] = 10;
alert(array[42]);​

看它在行动 此处.


13
投票
var array = new Uint8Array(100);    
array[10] = 256;
array[10] === 0 // true

我在firefox和chrome中验证了,它确实是一个字节数组。

var array = new Uint8Array(1024*1024*50);  // allocates 50MBytes

2
投票

你可以将数据存储在一个固定大小的字符串数组中。 访问该字符串数组中的任何一个特定字符,并将该字符视为一个字节,应该是很有效的。

如果能看到你想支持的操作,也许可以用接口的形式表达出来,使问题更加具体化,这将是很有趣的。


0
投票

我希望对这个问题有一个更准确和有用的答案。下面是真正的答案(如果你想要一个真正的答案,请相应调整 字节 数组;很明显,数学会偏离一个系数 8 bits : 1 byte):

class BitArray {
  constructor(bits = 0) {
    this.uints = new Uint32Array(~~(bits / 32));
  }

  getBit(bit) {
    return (this.uints[~~(bit / 32)] & (1 << (bit % 32))) != 0 ? 1 : 0;
  }

  assignBit(bit, value) {
    if (value) {
      this.uints[~~(bit / 32)] |= (1 << (bit % 32));
    } else {
      this.uints[~~(bit / 32)] &= ~(1 << (bit % 32));
    }
  }

  get size() {
    return this.uints.length * 32;
  }

  static bitsToUints(bits) {
    return ~~(bits / 32);
  }
}

用途:

let bits = new BitArray(500);
for (let uint = 0; uint < bits.uints.length; ++uint) {
  bits.uints[uint] = 457345834;
}
for (let bit = 0; bit < 50; ++bit) {
  bits.assignBit(bit, 1);
}
str = '';
for (let bit = bits.size - 1; bit >= 0; --bit) {
  str += bits.getBit(bit);
}
str;

输出。

"00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000101000101100101010
 00011011010000111111111111111111
 11111111111111111111111111111111"

注意:这个类的速度真的很慢,比如说分配比特(即每一千万次分配约2s)。 这个类的速度真的很慢,例如分配比特(即每一千万次分配约2s)。如果 它被创建为一个全局变量,至少在Linux上的Firefox 76.0控制台中是这样的...... 如果另一方面,它被创建为一个变量(即 let bits = new BitArray(1e7);), 然后神速 (即每1000万次作业约300ms)!


更多信息,请看这里。

请注意,我使用了Uint32Array,因为没有办法直接拥有一个比特字节数组(可以直接与之交互)。 因为即使有 BigUint64Array,JS只支持32位。

位元运算符将其操作数视为32位的序列。

...

所有位运算符的操作数都被转换为...32位整数。

© www.soinside.com 2019 - 2024. All rights reserved.