Node.js in Practice 读书笔记 (第三章Buffers 下)

    jwolf 
924  0  0   2016-1-20 9:02


Buffer处理字节流的使用例子:

处理URIs

首先简单谈谈URIs: URI指定了一个协议用来接收信息,包括一些关于资源的额外的信息。使用data URI获取图片时能减少额外的HTTP请求从而实现性能优化。URI的结构如下:

data:[MIME-type][;charset=<encoding>[;base64],<data>

使用下面代码能把图片输出为能被<img/>标签引用的URI:

var fs = require('fs');
var mime = 'image/png';

var encoding = 'base64';

var data = fs.readFileSync('./monkey.png').toString(encoding); 
var uri = 'data:' + mime + ';' + encoding + ',' + data; 
console.log(uri);

相反,把URI还原为图片文件:

var fs = require('fs');
var uri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAo...';
var data = uri.split(',')[1];
var buf = Buffer(data, 'base64');
fs.writeFileSync('./secondmonkey.png', buf);

后面一小节是利用buffer处理一个数据库文件,转换成一个json对象。

最后一节是实现自己的字节流协议:

在该例子中,协议会实现:

1. 使用掩码来决定信息存储在哪一个数组中(8个数据数组);

2. 数据中键值对的键是一个字节的大小(无符号整型)

3. 存储的信息无论多大都是使用zlib压缩过


1和2这里不再详述,主要利用二进制的&运算,8个数据数组对应一个字节的8位。

var database = [ [], [], [], [], [], [], [], [] ]; 
var bitmasks = [ 1, 2, 4, 8, 16, 32, 64, 128 ]; 
function store (buf) { 
    var db = buf[0];
    var key = buf.readUInt8(1); 
    bitmasks.forEach(function (bitmask, index) { 
        if ( (db & bitmask) === bitmask) { 
            database[index][key] = 'some data';
        } 
    });
 }

在string数据发送到网络之前进行压缩是非常必要的,Node提供了一个内置的zlib模块来实现数据压缩。在处理数据之前,为了防止重复处理数据,我们先检测数据是否已经被解压,一般来说,被zlib压缩过的数据时以 0x78开头的。另外,根据协议,我们从第二个字节开始解压数据:

var zlib = require('zlib');
var database = [ [], [], [], [], [], [], [], [] ];
var bitmasks = [ 1, 2, 4, 8, 16, 32, 64, 128 ];
function store (buf) {
    var db = buf[0];
    var key = buf.readUInt8(1);
    if (buf[2] === 0x78) {
        zlib.inflate(buf.slice(2), function (er, inflatedBuf) {
            if (er) return console.error(er);
            var data = inflatedBuf.toString();
            bitmasks.forEach(function (bitmask, index) {
                if ( (db & bitmask) === bitmask) {
                    database[index][key] = data;
                }
            });
        });
     }
}

最后利用我们的协议,我们压缩一些数据并利用上面的代码把数据保存到数组:

var zlib = require('zlib');
var header = new Buffer(2);
header[0] = 8;
header[1] = 0;
zlib.deflate('my message', function (er, deflateBuf) {
    if (er) return console.error(er);
    var message = Buffer.concat([header, deflateBuf]);
    store(message);
})