If you are using node-redis for saving the data then it will deal with Buffers directly so you can simply client.set(key, buff) or client.append(key, buff), so you don't need (want) to do any conversion.
Node.js (simplified from Kevin)
var zlib = require('zlib');
var redis = require("redis");
var rc = redis.createClient(null, null, {detect_buffers: true}); // allow Buffers
var message = new Buffer('My message');
zlib.deflate(message, function (err, deflated) {
if (err) return console.error(err);
rc.set("testkey", deflated, function (err, result) {
if (err) return console.error(err);
rc.quit();
});
});
Ruby code (copied from Kevin above)
require 'zlib'
require 'rubygems'
require 'redis'
redis = Redis.new
def inflate(buffer)
zstream = Zlib::Inflate.new
buf = zstream.inflate(buffer)
zstream.finish
zstream.close
buf
end
value = redis.get("testkey")
puts inflate(value)
That works in retrieving the value properly, but changing the Node.js code to use .toString('binary')
like you mention originally breaks the Ruby decoding like you said above.
Here is an example to show that toString('binary') does mess with the data
console.log(deflated);
console.log(new Buffer(deflated.toString('binary')));
So I can't figure out what transformation Buffer.toString('binary') is doing since I believe it goes into the V8 Buffer code.
But if you are still able to read it with Node, then you might want to extract it back out and save it the proper way without using the .toString('binary')
just give the Buffer to the redis client set method and it will save it properly.
Then it will be stored as binary and you can read it with ruby correctly using code like above.
As for your node.js code, once you have it saving as binary properly (using Buffer directly in set call), then to retrieve it:
var rc = redis.createClient(null, null, {detect_buffers: true}); // allow Buffers
rc.get(new Buffer(key), function (err, buff) { // use a Buffer for the key
// buff is a Buffer now
});
By having detect_buffers turned on for node-redis, then when you pass a Buffer in as a key, then it will retrieve as a Buffer and won't convert.
You could alternatively used return_buffers = true
option, but I like detect_buffers
so you can use the same client for both Buffer and non-Buffer data.
PS. Make sure for your Ruby gem that you are using one of the latest versions, not an old one like 1.x (2.x added binary fixes).