将缓冲区转换为数组

36

我正在设置memcached

$memcached->set("item" , ["1" => "hello"]);

无论什么东西在PHP中都可以工作,

在使用Node.js和memcached插件时,我得到的结果是一个缓冲区而不是数组。

<Buffer 61 3a 25 61 34 3a>

我无法将这样的缓冲区转换为数组

在Node.js中:

memcached.get("item" , function(err, data) {
  console.log(data);
}

你有任何方法吗?


如果在PHP中只调用$memcached->set("item" , "hello");会发生什么? - SheetJS
它获取字符串,没有问题。 - Ata
$memcached->set("item" , ["1", "hello"]); 这样写数组是否正确,我在想 PHP 是否有问题。 - SheetJS
我也可以将其作为数组处理,可能是PHP序列化了它,同时我使用了以下代码得到了一个数组:phpjs.unserialize(data.toString()); - Ata
7个回答

70

arr = [...buffer]

ES6 引入了许多其他功能,除了缓冲区。

你甚至可以像这样轻松地进行追加:

arr.push(...buffer)

... 运算符在数组中扩展可枚举对象,如数组和缓冲区。它还将它们扩展为单独的函数参数。


没错,它也更快:

... : x100000: 835.850毫秒

从原型中调用切片 : x100000: 2118.513毫秒

var array,
    buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]),
    iter = 100000;

array = buffer;

console.time("... : x" + iter);
for (var i = iter; i--;) array = [...buffer]
console.timeEnd("... : x" + iter);

console.time("Apply/call/etc : x" + iter);
for (var i = iter; i--;) array = Array.prototype.slice.call(buffer, 0)
console.timeEnd("Apply/call/etc : x" + iter);

18

还有另一种将其转换为整数数组的方法

使用toJSON()

Buffer.from('Text of example').toJSON()
{ type: 'Buffer',data: [ 84, 101, 120, 116, 32, 111, 102, 32, 101, 120, 97, 109, 112, 108, 101 ] }

// simple get data
Buffer.from('Text of example').toJSON().data
[ 84, 101, 120, 116, 32, 111, 102, 32, 101, 120, 97, 109, 112, 108, 101 ]

基准测试示例

// I took this from @user4584267's answer
const buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]);
let array = null;
const iterations = 100000;

console.time("...buffer");
for (let i = iterations; i=i-1;) array = [...buffer]
console.timeEnd("...buffer");

console.time("array.prototype.slice.call");
for (let i = iterations; i=i-1;) array = Array.prototype.slice.call(buffer, 0)
console.timeEnd("array.prototype.slice.call");

console.time("toJSON().data");
for (let i = iterations; i=i-1;) array = buffer.toJSON().data
console.timeEnd("toJSON().data");

输出

...缓冲区:559.932毫秒
数组原型切片调用:1176.535毫秒
toJSON().data:30.571毫秒

或者如果您想在Buffer中使用更多的专业和自定义功能,请使用此函数:

Buffer.prototype.toArrayInteger = function(){
    if (this.length > 0) {
        const data = new Array(this.length);
        for (let i = 0; i < this.length; i=i+1)
            data[i] = this[i];
        return data;
    }
    return [];
}

基准测试示例:

const buffer = new Buffer([1, 4, 4, 5, 6, 7, 5, 3, 5, 67, 7, 4, 3, 5, 76, 234, 24, 235, 24, 4, 234, 234, 234, 325, 32, 6246, 8, 89, 689, 7687, 56, 54, 643, 32, 213, 2134, 235, 346, 45756, 857, 987, 0790, 89, 57, 5, 32, 423, 54, 6, 765, 65, 745, 4, 34, 543, 43, 3, 3, 3, 34, 3, 63, 63, 35, 7, 537, 35, 75, 754, 7, 23, 234, 43, 6, 247, 35, 54, 745, 767, 5, 3, 2, 2, 6, 7, 32, 3, 56, 346, 4, 32, 32, 3, 4, 45, 5, 34, 45, 43, 43]);
let array = null;
const iterations = 100000;

console.time("toArrayInteger");
for (let i = iterations; i=i-1;) buffer.toArrayInteger();
console.timeEnd("toArrayInteger");

输出:

toArrayInteger: 28.714毫秒

注意: 在最后一个例子中,我从Buffer.toJSON中复制了一个函数并进行了轻微的自定义。


11

给你:

var buffer = new Buffer([1,2,3])
var arr = Array.prototype.slice.call(buffer, 0)
console.log(arr)

8
你能否在回答中多加一些细节?谢谢! - maxshuty
2
需要什么额外的细节?! - Dave Newton
非常简洁的回答,太棒了!谢谢,我之前很费劲地阅读那些愚蠢的段落。 - murage kibicho

3

我没有使用过memcached,所以不确定这个缓冲区代表什么,或者你想要替换成什么。很抱歉。这里有一个函数可以将缓冲区拆分成字节数组。更多信息请查看node.js 缓冲区文档,希望能帮到你!

var hex = new Buffer("613a2561343a", "hex");
var l = hex.length; // in bytes
var output = [];
for(var i = 0; i < l; i++){
  var char = hex.toString('hex',i,i+1); // i is byte index of hex
  output.push(char);
};
console.log(output);
// output: [ '61', '3a', '25', '61', '34', '3a' ]

1
它只是分割缓冲数据,不会将每个项目转换为使用的字符。 - Ata
明白了。也许有一种方法可以让PHP将非编码字符串保存到memcached中?我也不是很清楚,抱歉 - 祝你好运! - Plato

2
您也可以使用 Array.from:
memcached.get("item" , function(err, data) {
  console.log(Array.from(data));
}

1

我有一个解决方案,尽管目前我正在努力寻找更好的解决方案:

function bufToArray(buffer) {
  let array = new Array();
  for (data of buffer.values()) array.push(data);
  return array;
}

编辑:我找到了一种更简单的方法:

var buffer = Buffer.from('NodeJS rocks!')
var array = new Function(`return [${Array.prototype.slice.call(buffer, 0)}]`)

但是,正如有人已经说过的那样,[...buffer] 更快(且更代码高效)。

你也可以使用 new Uint8Array(buffer [, byteOffset [, length]]);


“a simpler way”是eval,在这里完全不必要。 - Estus Flask
你为什么需要一个函数构造器?它比“var array = Array.prototype.slice.call(buffer, 0);”更高效或者在任何方面都更好吗? - code

-3

在互联网上,没有关于这个的信息,但我已经找到了转换的方法。

在Node.js中,我必须使用:

var arrayobject = phpjs.unserialize(data.toString());

但是,这种获取数组的方式非常愚蠢,似乎 PHP 在设置 Memcache 时会对数据进行序列化。


你可以尝试将数组存储为JSON。$memcached->set("item" , json_encode(["1" => "hello"])); 然后在node.js中解码JSON。 - gen_Eric
是的,那是一种方式,但是我认为我们可以在每秒编码解码速率方面获得更高的比率,这样做并不高效。 - Ata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接