做东西的网站有那些,建站好的公司,网站广告条效果,物业网站模板Stream(流)
Stream 是 Node.js 中非常重要的一个模块#xff0c;应用广泛。
Stream 是一个抽象接口#xff0c;Node 中有很多对象实现了这个接口。例如#xff0c;对http 服务器发起请求的request 对象就是一个 Stream#xff0c;还有stdout#xff08;标准输出#xf…Stream(流)
Stream 是 Node.js 中非常重要的一个模块应用广泛。
Stream 是一个抽象接口Node 中有很多对象实现了这个接口。例如对http 服务器发起请求的request 对象就是一个 Stream还有stdout标准输出。
该抽象接口是可读、可写或是既可读又可写的通过这些接口我们可以和磁盘文件、套接字、HTTP请求来交互实现数据从一个地方流动到另一个地方的功能。
Node.jsStream 有四种流类型 Readable - 可读操作。 Writable - 可写操作。 Duplex - 可读可写操作. Transform - 操作被写入数据然后读出结果。
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有 data - 当有数据可读时触发。 end - 没有更多的数据可读时触发。 error - 在接收和写入过程中发生错误时触发。 finish - 所有数据已被写入到底层系统时触发
从流中读取数据
创建 input.txt 文件内容如下
百度以下你就知道创建 main.js 文件, 代码如下
var fs require(fs);
var data ;// 创建可读流
var readerStream fs.createReadStream(input.txt);// 设置编码为 utf8。
readerStream.setEncoding(UTF8);// 处理流事件 -- data, end, and error
readerStream.on(data, function(chunk) {data chunk;
});readerStream.on(end,function(){console.log(data);
});readerStream.on(error, function(err){console.log(err.stack);
});console.log(程序执行完毕);以上代码执行结果如下
程序执行完毕
百度以下你就知道写入流
创建 main.js 文件, 代码如下
var fs require(fs);
var data W3Cschool教程官网地址www.w3cschool.cn;// 创建一个可以写入的流写入到文件 output.txt 中
var writerStream fs.createWriteStream(output.txt);// 使用 utf8 编码写入数据
writerStream.write(data,UTF8);// 标记文件末尾
writerStream.end();// 处理流事件 -- data, end, and error
writerStream.on(finish, function() {console.log(写入完成。);
});writerStream.on(error, function(err){console.log(err.stack);
});console.log(程序执行完毕);以上程序会将 data 变量的数据写入到 output.txt 文件中。代码执行结果如下
$ node main.js
程序执行完毕
写入完成。查看 output.txt 文件的内容
$ cat output.txt
W3Cschool教程官网地址www.w3cschool.cn管道流
管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。 如上面的图片所示我们把文件比作装水的桶而水就是文件里的内容我们用一根管子(pipe)连接两个桶使得水从一个桶流入另一个桶这样就慢慢的实现了大文件的复制过程。
以下实例我们通过读取一个文件内容并将内容写入到另外一个文件中。
设置 input.txt 文件内容如下
百度一下你就知道
管道流操作实例创建 main.js 文件, 代码如下
var fs require(fs);// 创建一个可读流
var readerStream fs.createReadStream(input.txt);// 创建一个可写流
var writerStream fs.createWriteStream(output.txt);// 管道读写操作
// 读取 input.txt 文件内容并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);console.log(程序执行完毕);代码执行结果如下
$ node main.js
程序执行完毕查看 output.txt 文件的内容
$ cat output.txt
百度一下你就知道
管道流操作实例链式流
链式是通过连接输出流到另外一个流并创建多个对个流操作链的机制。链式流一般用于管道操作。
接下来我们就是用管道和链式来压缩和解压文件。
创建 compress.js 文件, 代码如下
var fs require(fs);
var zlib require(zlib);// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream(input.txt).pipe(zlib.createGzip()).pipe(fs.createWriteStream(input.txt.gz));console.log(文件压缩完成。);代码执行结果如下
$ node compress.js
文件压缩完成。执行完以上操作后我们可以看到当前目录下生成了 input.txt 的压缩文件 input.txt.gz。
接下来让我们来解压该文件创建 decompress.js 文件代码如下
var fs require(fs);
var zlib require(zlib);// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream(input.txt.gz).pipe(zlib.createGunzip()).pipe(fs.createWriteStream(input.txt));console.log(文件解压完成。);代码执行结果如下
$ node decompress.js
文件解压完成。 模块系统
为了让Node.js的文件可以相互调用Node.js提供了一个简单的模块系统。
模块是Node.js 应用程序的基本组成部分文件和模块是一一对应的。换言之一个 Node.js 文件就是一个模块这个文件可能是js 代码、JSON或者编译过的C/C 扩展。
创建模块
在 Node.js 中创建一个模块非常简单如下我们创建一个 main.js 文件代码如下:
var hello require(./hello);
hello.world();以上实例中代码 require(./hello) 引入了当前目录下的hello.js文件./ 为当前目录node.js默认后缀为js。
Node.js 提供了exports 和 require 两个对象其中 exports 是模块公开的接口require 用于从外部获取一个模块的接口即所获取模块的 exports 对象。
接下来我们就来创建hello.js文件代码如下
exports.world function() {console.log(Hello World);
}在以上示例中hello.js 通过 exports 对象把 world 作为模块的访 问接口在 main.js 中通过 require(./hello) 加载这个模块然后就可以直接访 问hello.js 中 exports 对象的成员函数了。
有时候我们只是想把一个对象封装到模块中格式如下
module.exports function() {// ...
}例如:
//hello.js
function Hello() { var name; this.setName function(thyName) { name thyName; }; this.sayHello function() { console.log(Hello name); };
};
module.exports Hello;这样就可以直接获得这个对象了
//main.js
var Hello require(./hello);
hello new Hello();
hello.setName(BYVoid);
hello.sayHello(); 模块接口的唯一变化是使用 module.exports Hello 代替了exports.world function(){}。 在外部引用该模块时其接口对象就是要输出的 Hello 对象本身而不是原先的 exports。 服务端的模块放在哪里
也许你已经注意到我们已经在代码中使用了模块了。像这样
var http require(http);...http.createServer(...);Node.js中自带了一个叫做http的模块我们在我们的代码中请求它并把返回值赋给一个本地变量。
这把我们的本地变量变成了一个拥有所有 http 模块所提供的公共方法的对象。
Node.js 的 require方法中的文件查找策略如下
由于Node.js中存在4类模块原生模块和3种文件模块尽管require方法极其简单但是内部的加载却是十分复杂的其加载优先级也各自不同。如下图所示 从文件模块缓存中加载
尽管原生模块与文件模块的优先级不同但是都不会优先于从文件模块的缓存中加载已经存在的模块。
从原生模块加载
原生模块的优先级仅次于文件模块缓存的优先级。require 方法在解析文件名之后优先检查模块是否在原生模块列表中。以 http 模块为例尽管在目录下存在一个http/http.js/http.node/http.json文件require(http) 都不会从这些文件中加载而是从原生模块中加载。
原生模块也有一个缓存区同样也是优先从缓存区加载。如果缓存区没有被加载过则调用原生模块的加载方式进行加载和执行。
从文件加载
当文件模块缓存中不存在而且不是原生模块的时候Node.js会解析require方法传入的参数并从文件系统中加载实际的文件加载过程中的包装和编译细节在前一节中已经介绍过这里我们将详细描述查找文件模块的过程其中也有一些细节值得知晓。
require方法接受以下几种参数的传递
http、fs、path等原生模块。./mod或../mod相对路径的文件模块。/pathtomodule/mod绝对路径的文件模块。mod非原生模块的文件模块。
在路径 Y 下执行 require(X) 语句执行顺序
1. 如果 X 是内置模块a. 返回内置模块b. 停止执行
2. 如果 X 以 / 开头a. 设置 Y 为文件根路径
3. 如果 X 以 ./ 或 / or ../ 开头a. LOAD_AS_FILE(Y X)b. LOAD_AS_DIRECTORY(Y X)
4. LOAD_NODE_MODULES(X, dirname(Y))
5. 抛出异常 not foundLOAD_AS_FILE(X)
1. 如果 X 是一个文件, 将 X 作为 JavaScript 文本载入并停止执行。
2. 如果 X.js 是一个文件, 将 X.js 作为 JavaScript 文本载入并停止执行。
3. 如果 X.json 是一个文件, 解析 X.json 为 JavaScript 对象并停止执行。
4. 如果 X.node 是一个文件, 将 X.node 作为二进制插件载入并停止执行。LOAD_INDEX(X)
1. 如果 X/index.js 是一个文件, 将 X/index.js 作为 JavaScript 文本载入并停止执行。
2. 如果 X/index.json 是一个文件, 解析 X/index.json 为 JavaScript 对象并停止执行。
3. 如果 X/index.node 是一个文件, 将 X/index.node 作为二进制插件载入并停止执行。LOAD_AS_DIRECTORY(X)
1. 如果 X/package.json 是一个文件,a. 解析 X/package.json, 并查找 main 字段。b. let M X (json main 字段)c. LOAD_AS_FILE(M)d. LOAD_INDEX(M)
2. LOAD_INDEX(X)LOAD_NODE_MODULES(X, START)
1. let DIRSNODE_MODULES_PATHS(START)
2. for each DIR in DIRS:a. LOAD_AS_FILE(DIR/X)b. LOAD_AS_DIRECTORY(DIR/X)NODE_MODULES_PATHS(START)
1. let PARTS path split(START)
2. let I count of PARTS - 1
3. let DIRS []
4. while I 0,a. if PARTS[I] node_modules CONTINUEb. DIR path join(PARTS[0 .. I] node_modules)c. DIRS DIRS DIRd. let I I - 1
5. return DIRS
exports 和 module.exports 的使用如果要对外暴露属性或方法就用 exports 就行要暴露对象(类似class包含了很多属性和方法)就用 module.exports。