从节点docs关于从Buffers:
创建类型化数组缓冲区的内存被解释为数组,而不是字节数组。那 是,
new Uint32Array(new Buffer([1,2,3,4]))
创建一个4元素 元素Uint32Array
的{{1}},而不是[1,2,3,4]
元素Uint32Array
或[0x1020304]
。
这与普通的javascript形成对比,其中从ArrayBuffer创建类型化数组视图使用ArrayBuffer的内存作为字节(如C ++中的[0x4030201]
)。在节点缓冲区上运行时,我在节点中需要这种行为。
我可以将Buffer转换为ArrayBuffer,但这对我的应用来说太慢了。 (我尝试了很多方法 - 但它们都是O(n)时间。)(编辑:我发现的最快的方法是this,这是一个单一的memmove op并且相当快,但仍然在释放对原始缓冲区的引用之前,至少会有2倍的内存消耗。)
是否有任何(快速/ O(1))方式从缓冲区获取类型化数组,使用缓冲区的内容作为字节而不是元素?(所需的类型化数据元素大小是> ; 1个字节,不用说了。)
答案 0 :(得分:3)
据我所知,如果不在内存中复制数据,就无法做到这一点。
即使您的示例new Uint32Array(new Buffer([1,2,3,4]))
在内部也这样做(意味着它不是O(1))。
请注意,键入的数组只是ArrayBuffer
的视图(不是Buffer
,这是不可能的)。 new Uint32Array(array)
创建ArrayBuffer
个4 * array.length
个字节。您可以使用uint32Array.buffer
访问它。构造函数会将您的Buffer
与普通Array
区别开来。
我所知道的最佳解决方案是the one you already found。
使用Uint32Array
进行尝试的另一个问题是它depends on platform byte order。如果您想要安全,可以迭代Buffer
DataView
或使用findById
。
答案 1 :(得分:2)
从节点4.0开始,Buffers是Uint8Arrays,可以直接在它们上构建新视图:
var b = new Buffer([1,2,3,4]);
new Uint32Array(b.buffer, b.byteOffset);
这个迷你示例假设b
大于~4096(缓冲区拥有自己的内存块与共享更大块的阈值)。有关详细信息,请参阅Convert a binary NodeJS Buffer to JavaScript ArrayBuffer - 通常您应致电b.slice()
以仅对您拥有的内存进行操作。