如何在 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
返回类型化数组。为此,我们必须在此处处理 Buffer
、ArrayBuffer
和类型化数组。
让我们从 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);
现在缓冲区 d
和 b
包含相同的元素。这没什么特别的。
现在,如果您直接从 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。如果您在同一台机器上执行所有这些操作,那么执行上述步骤应该没问题。
对于一些 Int32Array a
,我试过这个:
var d = zlib.deflateSync(new Buffer(a));
但是当我这样做的时候
var b = new Int32Array(zlib.inflateSync(d));
我得到 b
,这与 a
不同。
我知道在压缩之前将数组转换为字符串的想法。这只是内存效率不高。
有没有办法有效地做到这一点?
这里的主要问题不在于放气和膨胀,因为这两个操作只是将数据从一个 Buffer
元素传输到另一个 Buffer
元素,反之亦然,正如预期的那样。这里的问题是如何将类型化数组(例如 Int32Array
)传输到 Buffer
,以及如何从 Buffer
返回类型化数组。为此,我们必须在此处处理 Buffer
、ArrayBuffer
和类型化数组。
让我们从 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);
现在缓冲区 d
和 b
包含相同的元素。这没什么特别的。
现在,如果您直接从 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。如果您在同一台机器上执行所有这些操作,那么执行上述步骤应该没问题。