Jul*_*oux 3 ruby zlib inflate node.js
我们的应用程序的一些部分是用Ruby编写的,其他部分是使用node.js编写的.
我们使用存储zlib块的redis存储库在它们之间共享数据.我们使用节点使用以下代码写入它:
zlib.deflate(xml.toString(), function(error, deflated) {
...
deflated.toString('binary'); // That's the string we write in Redis
...
});
Run Code Online (Sandbox Code Playgroud)
现在,我们使用Ruby(1.8.7)在redis商店中读取这些数据,我不得不说我不知道该怎么做.
我们从商店获得的典型字符串如下所示:
=> "xuAo \020ÿ\ná.£v½\030dÿCO½±:«¤(\004ƪÿ¾¬®5MÚ\003÷½IÞ q¤°²e°c¼òÈ×\000ó<ùM¸ÐAç\025ÜÈ\r|gê\016Ý/.é\020ãÆî×\003Ôç<Ýù2´F\n¨Å\020!zl \0209\034p|üÀqò\030\036m\020\e`\031¼ÏütÓ=ø¦U/ÔO±\177zB{\037½£-ðBu©ò¢X\000kb*Ó[V\024Y^½EÎ¥üpúrò¦\177ÁÃdÈ¢j\0353$a\027²q#¥]*Ýi3J8¤´füd\eså[³öʵ%\fcÇY\037ð¬ÿg§í^¥8£Õ§a¶\001=\r;¡¾\001\020Pí"
Run Code Online (Sandbox Code Playgroud)
当然,我尝试使用 Zlib::Inflate.new.inflate(compressed)但是失败了Zlib::DataError: incorrect header check.
我们应该对该字符串进行什么样的转换才能从Ruby中扩展呢?
PS:从节点充气它很容易并且有效,所以问题不在于我们如何压缩它.
我们应该对该字符串进行什么样的转换才能从Ruby中扩展呢?
UTF-8到Latin-1
理想情况下,只要您在Node端直接使用Buffers,就不需要进行任何转换.在下面的底部看到一对Node和Ruby代码块; 然而,问题的本质是关于可以单独在Ruby方面做些什么来解决这个问题.
require 'zlib'
require 'rubygems'
require 'redis'
require 'iconv'
redis = Redis.new
def inflate(buffer)
zstream = Zlib::Inflate.new
buf = zstream.inflate(buffer)
zstream.finish
zstream.close
buf
end
def convert(buffer)
utf8_to_latin1 = Iconv.new("LATIN1//TRANSLIT//IGNORE", "UTF8")
utf8_to_latin1.iconv(buffer)
end
value = redis.get("testkey")
value = convert(value)
puts inflate(value);
Run Code Online (Sandbox Code Playgroud)
上面的代码使用iconv将从Redis检索的值从UTF-8转换回预期的字节.
在Node中进行放气时,生成的缓冲区包含正确的zlib生成字节; 结果字符串from toString('binary'),character的字符也匹配deflate结果缓冲区的内容; 但是,当deflate结果存储在Redis中时,它是UTF-8编码的.一个例子:
放松字符串"ABCABC"会导致:
<Buffer 78 9c 73 74 72 76 74 72 06 00 05 6c 01 8d>
Run Code Online (Sandbox Code Playgroud)
然而,Redis回归:
<Buffer 78 c2 9c 73 74 72 76 74 72 06 00 05 6c 01 c2 8d>
Run Code Online (Sandbox Code Playgroud)
假设一点,似乎结果的字符串最终toString('binary')作为新缓冲区(...)的参数,可能在node-redis中.如果没有为新的Buffer()指定编码参数,则应用默认的UTF-8编码.(见第一篇参考文献).进一步假设,通过仅使用缓冲区,您无需从字符串创建缓冲区,因此,避免使用UTF8编码,因此正确的deflate值使其进出Redis.
参考
var zlib = require('zlib');
var redis = require("redis").createClient();
var message = new Buffer('your stuff goes here.');
//var message = new Buffer(xml.toString());
redis.on("error", function (err) {
console.log("Error " + err);
});
redis.on("connect", function() {
console.log(message);
zlib.deflate(message, function(error, deflated) {
console.log(deflated);
redis.set("testkey",deflated,function (err, reply) {
console.log(reply.toString());
});
});
});
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)