2017-05-11 22 views
0

私はredisを使ってビットフィールドのデータを保存していますが、オフセットごとにu4の値を設定します。
Nodejsサーバーでバッファを取得する必要があります。
0-7の場合、redisは正しいバッファを返します。
8-15の値を設定すると、奇妙なバッファが返されます.Unin8Arrayがバッファに表示され、[239,191,189]が表示され、乱雑なコードが表示されます。 ここにコピーを実行するテストコードがあります。
resoponseバッファで問題が発生しています。#0値を取得しようとしても問題ありません。なぜredisは[239、191、189]応答バッファを返しますか?

const http = require('http'); 
const url = require('url'); 
const fs = require('fs'); 
const redis = require('redis'), 
     RDS_PORT = 6379, 
     RDS_HOST = '139.199.33.69',//139.199.33.69 
     RDS_OPTS = {detect_buffers: true}, 
     client = redis.createClient(RDS_PORT, RDS_HOST, RDS_OPTS); 
console.log('redis ready') 
const canvas_name = 'canvas-bitfield'; 
client.del(canvas_name) 
client.send_command("bitfield",[canvas_name,'SET','u4','#0',10,'OVERFLOW','FAIL']) 

client.send_command('bitfield',[canvas_name,'GET','u4',0],redis.print) //reply:10 

client.get(canvas_name,function(err, reply){ 
    if(err){console.log(err)} 
    const buff = Buffer.from(reply.toString()); 
    const view8 = new Uint8Array(buff); 
    console.log(view8) //Uint8Array(3) [239, 191, 189] 
}) 
+0

これは無関係ですが、とにかくそれを指摘します:send_commandは*非同期*です。したがって、send_commandが真に終了した後に、後続のコマンドが実行されるようにcallbackパラメータを使用する必要があります。 'client.send_command(command、args、callback)' –

答えて

2

なぜRedisの[239、191、189]応答バッファを返しますか?

replyStringないBufferであることをここにお知らせ! なぜですか?よく、あなたはdetect_buffers: trueを使用しています。 redisパッケージのドキュメントから、このオプションをtrueに設定すると、タイプreplyclient.get()に渡される最初の引数のタイプによって異なります。あなたはそれを渡されたので文字列は(canvas_nameがStringである)、回答の値も文字列です:Buffer.toString()へ:仕事にこのため

client.get(canvas_name,function(err, reply){ 
    console.log(typeof reply) // => String 
    // ... 

redisパッケージinternallyは、関数呼び出しを行います<Buffer a0>のバッファをStringに変換し、このStringをコールバックに渡します。 replyに結合する。問題は、引数が渡されずにBuffer.toString()がUTF-8を使用してバッファをデコードしようとしますが、<Buffer a0>は有効なUTF-8文字列ではないという点です。 Node.jsはこの場合silently failsで、U + FFFDの置換文字を返します。したがってreply U + FFFDのちょうど1文字または65533です

client.get(canvas_name,function(err, reply){ 
    console.log(reply.length); // 1 
    console.log(reply.charCodeAt(0)) // => 65533 
    // ... 

この番号(65533)を含む文字列はUTF-8文字列としてあなたのバッファを解析するために失敗しのRedis(Node.jsの)から来ています!そこから、あなたが[239, 191, 189]の、バッファに65533を入れてUint8Arrayを作成します。

console.log(Buffer.from("\uFFFD")) // => <Buffer ef bf bd> 
console.log(new Uint8Array(Buffer.from("\uFFFD"))); // => Uint8Array(3) [239, 191, 189] 

はすぐにあなたの問題のために解決するには、Stringに バッファを変換しないようにredisパッケージを伝える必要があります。代わりに、直接バッファを取得:

client.get(new Buffer(canvas_name), function(err, reply) { 
    console.log(typeof reply) // => Buffer 
    console.log(reply) // => <Buffer a0> 
    if(err){console.log(err)} 
    const view8 = new Uint8Array(reply); 
    console.log(view8) // => Uint8Array(3) [160] 
}); 

注:0-7が正常にあなたが偶然正しいバッファを得た理由はUTF-8文字列としてデコードされる範囲内で小数点以下の値でバッファを。

+0

ありがとうございます!私は最終的にこれを{return_buffers:true}オプションで解決します。 – Natsu

+0

素晴らしい!あなたが役に立ったらこの回答を受け入れてください。 –

関連する問題