【问题标题】:Convert buffer to array将缓冲区转换为数组
【发布时间】:2013-08-11 12:17:06
【问题描述】:

我用

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

任何在 PHP 中工作的东西,

在带有 memcached 插件的 Node.js 中,我得到一个缓冲区而不是结果中的数组

<Buffer 61 3a 25 61 34 3a>

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

在 Node.js 中:

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

你有什么办法吗?

【问题讨论】:

  • 你有代码示例吗?
  • @nirik : 编辑,看看
  • 如果你只是在php中调用$memcached-&gt;set("item" , "hello");会发生什么?
  • 得到字符串没问题
  • $memcached-&gt;set("item" , ["1", "hello"]); 怎么样,不知道是不是 PHP 没有正确写入数组

标签: javascript node.js memcached


【解决方案1】:

在互联网上,没有相关信息,但我找到了转换方式

在 nodejs 中,我必须使用:

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

但是,获取数组的方式非常愚蠢,似乎php在设置memcache时对数据进行了序列化。

【讨论】:

  • 您可以尝试将数组存储为 JSON。 $memcached-&gt;set("item" , json_encode(["1" =&gt; "hello"]));。然后解码 node.js 中的 JSON。
  • 是的,就是这样,但是认为我们每秒编码解码的速率很高,这样,这不是有效的方式
【解决方案2】:

我没有使用过 memcached,所以我不确定这个缓冲区代表什么,或者你想拥有什么。对不起。这是一个将缓冲区拆分为字节数组的函数。更多node.js Buffer docs,希望对您有所帮助!

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' ]

【讨论】:

  • 它只是拆分缓冲区数据,它不会将每个项目转换为使用的字符
  • 明白了。也许有一种方法可以让 PHP 将非编码字符串保存到 memcached 中?我也不是很清楚,对不起 - 祝你好运!
【解决方案3】:

给你:

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

【讨论】:

  • 您能否在答案中添加更多细节?谢谢!
  • 还需要什么额外的细节?!
【解决方案4】:

arr = [...buffer]

除了缓冲区之外,ES6 还引入了许多其他特性。

您甚至可以像这样轻松附加:

arr.push(...buffer)

... 运算符在数组中使用时扩展数组和缓冲区等枚举。它还将它们扩展为单独的函数参数。


是的,它也更快:

... : x100000: 835.850ms

来自原型的切片调用:x100000:2118.513ms

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);

【讨论】:

    【解决方案5】:

    我有一个解决方案,虽然我目前正在寻找更好的解决方案:

    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]]);

    【讨论】:

    • '一个更简单的方法'是 eval 在这里完全不需要。
    【解决方案6】:

    还有另一种方法可以转换为整数数组

    使用 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.932ms
    array.prototype.slice.call:1176.535ms
    toJSON().data: 30.571ms

    或者如果您想在 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.714ms

    注意:在最后一个示例中,我从Buffer.toJSON 复制了一个函数并将其自定义为精简版

    【讨论】:

      【解决方案7】:

      你也可以使用Array.from:

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

      【讨论】:

        猜你喜欢
        • 2021-01-14
        • 2011-12-03
        • 1970-01-01
        • 1970-01-01
        • 2022-08-05
        • 2016-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多