如何在 node.js 中使用 zlib 压缩 TypedArray?

How to deflate a TypedArray uzing zlib in node.js?

对于一些 Int32Array a,我试过这个:

var d = zlib.deflateSync(new Buffer(a));

但是当我这样做的时候

var b = new Int32Array(zlib.inflateSync(d));

我得到 b,这与 a 不同。

我知道在压缩之前将数组转换为字符串的想法。这只是内存效率不高。

有没有办法有效地做到这一点?

这里的主要问题不在于放气和膨胀,因为这两个操作只是将数据从一个 Buffer 元素传输到另一个 Buffer 元素,反之亦然,正如预期的那样。这里的问题是如何将类型化数组(例如 Int32Array)传输到 Buffer,以及如何从 Buffer 返回类型化数组。为此,我们必须在此处处理 BufferArrayBuffer 和类型化数组。

让我们从 Int32Array a 开始:

var a = new Int32Array([3,-2,258]);

如果您直接使用 var b = new Buffer(b); 从这个类型化数组创建一个 Buffer,您将得到一个包含 3 个字节而不是 12 个字节的缓冲区(Int32Array 中的每个元素有 4 个字节), 这意味着你会丢失一些信息。正确的做法是从 ArrayBuffer 创建 Buffer。你可以这样做:

var b = new Buffer(a.buffer);

这样你就得到了一个 Buffer,其中包含 12 个字节。现在很容易放气和充气这个缓冲区 b:

var c = zlib.deflateSync(b);
var d = zlib.inflateSync(c);

现在缓冲区 db 包含相同的元素。这没什么特别的。

现在,如果您直接从 Buffer d 创建 Int32Array,您将获得应有的 4 倍的元素,因为 Buffer [=31] 中的每个字节=] 将映射到 Int32Array 中的一个元素。为了克服这个问题,我们将使用 Uint8Array:

var e = new Uint8Array(d);

我们使用 Uint8Array 只是将缓冲区 d 的每个字节映射到我们现在可以访问其 ArrayBuffer 的类型化数组的一个字节。最后一步是从类型数组 e:

ArrayBuffer 创建最终的 Int32Array
var f = new Int32Array(e.buffer);

最后我们得到 f 看起来和 a 一样。

请注意,上面的某些步骤取决于 Endianness。如果您在同一台机器上执行所有这些操作,那么执行上述步骤应该没问题。