js
起初就是为浏览器而设计的,因此能很好的处理unicode
编码的字符串,但不能很好的处理二进制数据。这是Node.js
的一个问题,由于Node.js
旨在网络上发送和接收常常是以二进制格式传输的数据。好比:node
- 经过TCP链接发送和接收数据; - 从图像或者压缩文件读取二进制数据; - 从文件系统读写数据; - 处理来自网络的二进制数据流
而Buffer
模块为Node.js
带来了一种存储原始数据的方法,因而能够再js
的上下文中使用二进制数据。每当须要在Node.js
中处理I/O
操做中移动的数据时,就有可能使用Buffer模块。数组
Buffer
类是一个全局变量类型,用来直接处理2进制数据的。 它可以使用多种方式构建。浏览器
原始数据保存在 Buffer
类的实例中。一个 Buffer
实例相似于一个整数数组网络
1.new Buffer(size):分配一个新的 buffer 大小是 size 的8位字节. 2.new Buffer(array):分配一个新的 buffer 使用一个8位字节 array 数组. 3.new Buffer(str, [encoding]):encoding String类型 - 使用什么编码方式,参数可选. 4.类方法: Buffer.isEncoding(encoding):若是给定的编码 encoding 是有效的,返回 true,不然返回 false。 5.类方法: Buffer.isBuffer(obj):测试这个 obj 是不是一个 Buffer. 返回Boolean 6.类方法: Buffer.concat(list, [totalLength]):list {Array}数组类型,Buffer数组,用于被链接。totalLength {Number}类型 上述Buffer数组的全部Buffer的总大小。
除了能够读取文件获得Buffer
的实例外,还可以直接构造,例如:测试
var bin = new Buffer([ 0x48, 0x65, 0x6c, 0x6c, 0x6c ]);
Buffer
与字符串相似,除了能够用.length
属性获得字节长度外,还能够用[index]
方式读取指定位置的字节,例如:ui
bin[0]; // => 0x48;
Buffer
与字符串可以互相转化,例如可使用指定编码将二进制数据转化为字符串:this
var str = bin.toString('utf-8'); // => "hello"
.slice
方法不是返回一个新的Buffer
,而更像是返回了指向原Buffer
中间的某个位置的指针,以下所示。编码
1.[ 0x48, 0x65, 0x6c, 0x6c, 0x6c ] 2. ^ ^ 3. | | 4. bin bin.slice(2)
var buffer = new Buffer(8);//建立一个分配了8个字节内存的缓冲区 console.log(buffer.write('a','utf8'));//输出1
这会将字符"a"
写入缓冲区,node
返回通过编码之后写入缓冲区的字节数量,这里的字母a
的utf-8
编码占用1个字节。操作系统
Node.js
提供了一个将Buffer
对象总体内容复制到另外一个Buffer
对象中的方法。咱们只能在已经存在的Buffer
对象之间复制,因此必须建立它们。设计
buffer.copy(bufferToCopyTo)
其中,bufferToCopyTo
是要复制的目标Buffer对象。以下示例:
var buffer1 = new Buffer(8); buffer1.write('nice to meet u','utf8'); var buffer2 = new Buffer(8); buffer1.copy(buffer2); console.log(buffer2.toString());//nice to meet u
在UNIX
类型的操做系统中,流是个标准的概念。有以下三个主要的流:
1.标准输入 2.标准输出 3.标准错误
若是说,缓冲区是Node.js
处理原始数据的方式的话,那么流一般是Node.js
移动数据的方式。Node.js
中的流是可读的或者可写的。Node.js
中许多模块都使用了流,包括HTTP
和文件系统。
假设咱们建立一个classmates.txt
的文件,并从中读入姓名清单,以便使用这些数据。因为数据是流,这就意味着完成文件读取以前,从收到最初几个字节开始,就能够对数据动做,这是Node.js
中的一个常见模式:
var fs = require('fs'); var stream = fs.ReadStream('classmates.txt'); stream.setEncoding('utf8'); stream.on('data', function (chunk) { console.log('read some data') }); stream.on('close', function () { console.log('all the data is read') });
在以上示例中,在收到新数据时触发事件数据。当文件读取完成后触发关闭事件。
显然,咱们也能够建立可写流以便写数据。这意味着,只要一段简单的脚本,就可使用流读入文件而后写入另外一个文件:
var fs = require('fs'); var readableStream = fs.ReadStream('classmates.txt'); var writableStream = fs.writeStream('names.txt'); readableStream.setEncoding('utf8'); readableStream.on('data', function (chunk) { writableStream.write(chunk); }); readableStream.on('close', function () { writableStream.end(); });
如今,当接收到数据事件时,数据会被写入可写流中。
readable.setEncoding(encoding):返回: this readable.resume():同上。该方法让可读流继续触发 data 事件。 readable.pause():同上。该方法会使一个处于流动模式的流中止触发 data 事件,切换到非流动模式,并让后续可用数据留在内部缓冲区中。
Writable
(可写)流接口是对您正在写入数据至一个目标的抽象。
1.writable.write(chunk, [encoding], [callback]): chunk {String | Buffer} 要写入的数据 encoding {String} 编码,假如 chunk 是一个字符串 callback {Function} 数据块写入后的回调 返回: {Boolean} 若是数据已被所有处理则 true。
该方法向底层系统写入数据,并在数据被处理完毕后调用所给的回调。
2.writable.cork():强行滞留全部写入。
滞留的数据会在 .uncork()
或 .end()
调用时被写入。
3.writable.end([chunk], [encoding], [callback]) chunk {String | Buffer} 可选,要写入的数据 encoding {String} 编码,假如 chunk 是一个字符串 callback {Function} 可选,流结束后的回调
在调用 end()
后调用 write()
会产生错误。
// 写入 'hello, ' 而后以 'world!' 结束 http.createServer(function (req, res) { res.write('hello, '); res.end('world!'); // 如今不容许继续写入了 });