资讯专栏INFORMATION COLUMN

Node.js知识点详解(三)缓冲与流模块

plus2047 / 1283人阅读

摘要:缓冲模块起初就是为浏览器而设计的,所以能很好的处理编码的字符串,但不能很好的处理二进制数据。有如下三个主要的流标准输入标准输出标准错误可读流如果说,缓冲区是处理原始数据的方式的话,那么流通常是移动数据的方式。该方法让可读流继续触发事件。

缓冲(buffer)模块

js起初就是为浏览器而设计的,所以能很好的处理unicode编码的字符串,但不能很好的处理二进制数据。这是Node.js的一个问题,因为Node.js旨在网络上发送和接收经常是以二进制格式传输的数据。比如:

 - 通过TCP连接发送和接收数据;
 - 从图像或者压缩文件读取二进制数据;
 - 从文件系统读写数据;
 - 处理来自网络的二进制数据流

Buffer模块为Node.js带来了一种存储原始数据的方法,于是可以再js的上下文中使用二进制数据。每当需要在Node.js中处理I/O操作中移动的数据时,就有可能使用Buffer模块。

类: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]方式读取指定位置的字节,例如:

bin[0]; // => 0x48;

Buffer与字符串能够互相转化,例如可以使用指定编码将二进制数据转化为字符串:

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返回经过编码以后写入缓冲区的字节数量,这里的字母autf-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 事件,切换到非流动模式,并让后续可用数据留在内部缓冲区中。 
类: stream.Writable

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!");
  // 现在不允许继续写入了
});

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85468.html

相关文章

  • nodeJs文件系统(fs)与流(stream)

    摘要:异步文件系统不会阻塞程序的执行,而是在操作完成时,通过回调函数将结果返回。 文件系统(File System): 在Node中,文件系统的交互是非常重要的,服务器的本质就是将本地的文件发送给客户端, Node通过fs模块来和文件系统进行交互,该模块提供了一些标准的文件访问API类打开、读取、写入文件、以及与其交互。 要是用fs模块,首先要从核心模块中加载; 使用 const fs= ...

    0x584a 评论0 收藏0
  • 后端识点总结——NODE.JS基础

    摘要:后端知识点总结基础不是是一种软件开发平台,它的竞争对象历史第一次有一种语言可以通吃前后端网站阿里云镜像版本年初年中年底最新版本功能强大可靠,适合大型企业级项目简单易用适合互联网项目易用适合平台性能好适合服务器端密集型项目不适合密集型项目密集 后端知识点总结——NODE.JS基础 1.Node.js Node.js不是JS,是一种软件开发平台,它的竞争对象JSP/PHP/ASP.NET...

    Freeman 评论0 收藏0
  • Node.js - 200 多行代码实现 Websocket 协议

    摘要:预备工作序最近正在研究相关的知识,想着如何能自己实现协议。监听事件就是协议的抽象,直接在上面监听已有的事件和事件这两个事件。表示当前数据帧为消息的最后一个数据帧,此时接收方已经收到完整的消息,可以对消息进行处理。 A、预备工作 1、序 最近正在研究 Websocket 相关的知识,想着如何能自己实现 Websocket 协议。到网上搜罗了一番资料后用 Node.js 实现该协议,倒也没...

    张巨伟 评论0 收藏0
  • Deno 兼容浏览器具体指的是什么?

    摘要:里面有一句描述,可以看到的目标是兼容浏览器。那么这里的兼容浏览器到底如何是什么意思呢我简单谈谈我的理解吧。很多人还有误解以为兼容浏览器指的是会提供类似里的写法。 Deno 里面有一句描述:Aims to be browser compatible,可以看到 Deno 的目标是兼容浏览器。那么这里的兼容浏览器到底如何是什么意思呢? 我简单谈谈我的理解吧。 首先这里的兼容性肯定不是 Den...

    Yangyang 评论0 收藏0

发表评论

0条评论

plus2047

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<