流是Node.js中一个非常重要的概念, 也是Node.js之所以适用于I/O密集型场景的重要原因之一。 流是Node.js移动数据的方式,流可以是可读的和/或可写的。在Node.js中很多模块都使用到了流, 包括HTTP和fs模块,本文将用尽可能简单的方式为你介绍Node中流的概念。
流 Stream
事实上,流通常用于将程序连接在一起。流可以被读和写。被流连接在一起的程序通常很小,并且只专注于做一件事。
你可能经常在项目中使用Gulp来做项目的代码构建,那么在使用过程中,你很可能碰到过类似下面的错误。 错误大概是这样个的:
stream.js:94 throw er; // Unhandled stream error in pipe.
当初次碰到这种错误的时候,你可能和我一样对流的概念毫无头绪,好在我们可以借助Google来寻找答案。 一个最佳的开始是用Google搜索“node stream”之类的关键字, 从而我们可以获得stream-adventure这类的课程学习。
在Node.js的文档中,流(Stream)的官方定义如下:
流是一个抽象接口,在Node.js中它借助于多种对象实现。例如,一个对HTTP服务器的请求是一个流, 可以是stdout。流是可读的,可写的,或两者兼备。所有的流都是
EventEmitter
的实例。
也就是说,Node.js中的很多模块都是用到了流,例如http
和fs
模块。例如在文件系统模块(fs
)中, 我们可以通过流来读写文件数据的实例。由于数据是流,这就意味着在完成文件读取之前, 从收到最初几个字节开始,就可以对数据动作。这是Node.js中的一个常见模式:
可读流
const fs = require('fs'); const stream = fs.ReadStream('name.txt'); stream.setEncoding('utf-8'); stream.on('data', chunk => { console.log('read some data'); }); stream.on('close', () => { console.log('all the data is read'); });
在上面的例子中,我们创建了一个可读流,并在流读取文件的过程中监听事件,在收到新数据时触发事件数据。 当文件读取完成后触发关闭事件。
此外,在流中,我们要负责按自己想要的方式使用数据,所以我们必须在数据事件接收到数据的时候处理它。 如果想要读区所有数据,就必须将其拼接到一个变量中:
let data = ''; stream.on('data', chunk => { data += chunk; console.log('read some data'); });
如果读取的文件很大,这就会触发多个data事件,这就需要开发者可以在以接收到数据的时候就做一些事情, 而不是等到整个文件都读取完成。
可写流
显然,我们也可以创建可写流以便写数据。这意味着,只要一段简单的脚本,就可以使用流读入文件然后写入另一文件:
const fs = require('fs'); let readStream = fs.ReadStream('name.txt'); let writeStream = fs.WriteStream('out.txt'); readStream.setEncoding('utf-8'); readStream.on('data', chunk => { writeStream.write(chunk); }); readStream.on('close', () => { writeStream.end(); });
在上面的例子中,当接收到data事件的时候,我们便将数据写入到可写流writeStream中,这非常的高效, 因为只要从可读文件接收到数据事件,数据就会被写入文件。尤其是对大文件而言,不会被阻塞。因此, 对于网络和文件系统中移动数据而言,流的方式非常的高效。
通过管道连接流
本质上,流允许你讲其他对象或程序连接在一起。你将某些输入,然后让它经过流, 将它传递到另一个程序中。我比较喜欢拿水管来做类比。将一组小型的管道(程序)连接在一起, 用于完成一些特定的任务。
管道(pipe)的概念很早就存在于Unix系统中,你可以通过这篇文章了解更多:Unix Pipelines
由于在输入和输出之间通过管道传输数据在Node.js中很常见,所以它也提供了连接两个可读和可写流并在它们之间通过管道传输数据的方法。 例如:readStream.pipe(writeStream)
。
pipe()
方法会仔细处理事件,在需要的时候会暂停流并恢复流操作,所以除非需要对事件的发生有完全的控制权, 否则应该使用pipe()
。
const fs = require('fs'); // 指定读取流,指向目标文件,编码格式为utf-8 const file = fs.createReadStream('hello.txt', {encoding: 'utf-8'}); // 流是EventEmitter的实例,我们可以为其添加事件 // 当打开文件时触发open事件 file.on('open', function () { // 使用管道,将文件内容输出到屏幕上 // process对象也是一个EventEmitter实例 this.pipe(process.stdout); });
References
- Introduction to streams
- Hack Reactor’s Video About Node Streams
- Stream (Node.js)
- File System (Node.js)
- Node Streams Article by Max Ogden
原文:http://wwsun.github.io/posts/stream-in-nodejs.html
相关推荐
7. 流(Stream):Node.js中的流是处理大数据和实时数据的强大工具,可以处理文件、网络、磁盘等数据源。 8. 模块系统:Node.js采用CommonJS模块规范,使得代码组织更加清晰,易于复用和维护。 通过以上简单的介绍...
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者能够在服务器端使用 JavaScript 进行开发,极大地推动了全栈开发的流行。本教程旨在为初学者提供一个快速学习 Node.js 的入口,帮助你从零开始...
6. **流(Stream)**:Node.js中的流是处理大量数据的有效方式,书中会解释什么是流、如何创建和操作流,以及它们在读写文件、网络传输等方面的应用。 7. **模块系统**:Node.js的模块化设计使得代码组织更加有序,书...
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让开发者能够使用 JavaScript 来进行服务器端编程。这个入门教程将带你走进 Node.js 的世界,了解其核心概念、工作原理以及如何利用它来开发高效的应用...
6. **流(Stream)**:Node.js中的流是处理大量数据的有效方式,允许数据以连续的方式流动,而无需一次性加载整个文件。 7. **中间件(Middleware)**:如Express框架中的中间件机制,用于构建复杂的Web应用程序。 8. **...
5. **流(Stream)**:Node.js的核心特性之一是流数据处理,讲解流的概念,以及如何在读写文件、网络传输等场景中运用流进行高效操作。 6. **数据库集成**:探讨MongoDB、MySQL等数据库与Node.js的集成,讲解Mongoose...
在本文中,我们将深入探讨Node.js,一个基于Chrome V8引擎的JavaScript运行环境。Node.js以其高效的非阻塞I/O模型和事件驱动架构而闻名,使得JavaScript能够在服务器端发挥强大的功能,不再局限于浏览器环境。本教程...
Node.js 是一种基于 Chrome V8 引擎的 JavaScript 运行环境,专为构建服务器端应用程序和网络工具而设计。它的出现使得 JavaScript 能够在服务器端执行,从而打破了 JavaScript 仅限于前端脚本的局限,实现了全栈...
《Node.js基础详解》 Node.js,作为一款基于Chrome V8引擎的...通过以上内容的学习,你将对Node.js有全面的认识,能够熟练地使用Node.js进行服务器端开发。不断实践和深入研究,你将在Node.js的世界里游刃有余。
4. **流(Stream)**:Node.js的流模块是处理大量数据的有效方式,如网络传输、文件读写。流分为可读、可写、Duplex和Transform四种类型,理解流的事件驱动和数据处理机制能提高性能。 5. **进程和线程(Process ...
Gulp的核心思想是使用“流”(Stream)来处理文件。流是一种数据处理方式,它可以将数据视为一系列连续的数据块,并且可以在这些数据块上进行操作。相较于Grunt等其他构建工具,Gulp避免了频繁的文件读写操作,而是...
在JavaScript的世界里,Stream是一种处理I/O操作的强大工具,它允许我们高效地处理大量数据,尤其是在合并文件时。Stream的概念源自Node.js...通过以上介绍,你应该对如何使用js代码和Stream来合并文件有了清晰的认识。
`gulp-auto` 是一个基于 Node.js 的自动化构建工具,主要服务于 JavaScript 开发流程中的构建任务。在现代 Web 开发中,构建工具扮演着至关重要的角色,它们能够简化复杂的项目管理,优化代码,提高开发效率。`gulp-...