一文聊聊Node中的stream(流)

什么是流?如何理解流?下面本篇文章就来带大家深入了解一下nodejs中的流(stream),希望对大家有所帮助!

一文聊聊Node中的stream(流)

stream 也就是流,可以理解为一连串的字节像水流那样的存在。按照官方文档的解释:

A stream is an abstract interface for working with streaming data in Node.js.

流是用于在 Node.js 中处理流数据,也就是连续字节的抽象接口。流有 4 种基本类型,本篇文章主要介绍其中两种 —— 可读流和可写流。

可读的(Readable)

我们可以通过 fs.createReadStream() 创建一个可读流 readableStream,第 1 个参数可以是要读取的文件路径,比如现有文件 test.txt 内容为:

hello juejin

第 2 个参数(可选)可以传入一个选项对象,用来控制读取数据的起止位置等: 【相关教程推荐:nodejs视频教程】

const fs = require('fs')const readableStream = fs.createReadStream('./test.txt', {  start: 6,  end: 11})

注意,读取的数据是包括了 startend 的。 在之前介绍 events 模块时说过,所有的流都是 EventEmitter 的实例。所以获取数据是通过监听 'data' 事件:

readableStream.on('data', data => {  console.log(data)  console.log(data.toString())})

打印结果如下,默认是 Buffer 对象,可以通过 toString() 方法转为字符串:

1.png

注意,读取数据时一次最多读取 64 * 1024 字节,如果想改变该数值,可以通过 highWaterMark 选项更改。另外还可以使用 pause() 进行暂停操作,使用 resume() 继续读取:

const readableStream = fs.createReadStream('./test.txt', {  start: 6,  end: 11,  highWaterMark: 2 // 默认为 64 * 1024})readableStream.on('data', data => {  console.log(data)  console.log(data.toString())  readableStream.pause() // 暂停读取  setTimeout(() => {    readableStream.resume() // 恢复读取  }, 2000)})

执行结果如下:

2.gif

除了 'data' 事件,可读流还有其它一些事件,比如监听文件被打开的 'open'(回调会被传入 fd 参数),监听文件读取到 end(默认为读取到最后)的 'end',监听文件关闭的 'close'(文件读取完会自动关闭):

文心一言 文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

文心一言 1008 查看详情 文心一言

readableStream.on('data', data => console.log(data))readableStream.on('open', fd => console.log(`${fd}文件打开了`))readableStream.on('end', () => console.log('文件读取到 end 位置了'))readableStream.on('close', () => console.log('文件已关闭'))

打印结果如下:

3.png

可写的(Writable)

使用 fs.createWriteStream() 可以创建可写流,第 1 个参数传入要写入的文件,第 2 个同样是用于配置的可选参数,这里我们将 flags 由表示覆盖写入的 'w' 改为 'a',即追加写入(如果还指定了写入的起始位置 start,则为了兼容 windows 系统, flags 应该写成 'r+'):

const writableStream = fs.createWriteStream('test.txt', {  flags: 'a'})writableStream.write('养成', err => console.log(`错误信息:${err}`)) // 错误信息:undefinedwritableStream.write('写作的')writableStream.end('好习惯')

写入数据是通过 write 方法,上方代码执行的结果就是在原本的 “hello juejin” 后添加上了 “养成写作的好习惯”。最后一次写入可以使用 end 方法,这样就能监听到可写流的 'close' 事件了:

writableStream.on('close', () => {  console.log('关闭')})

否则,可写流需要手动 writableStream.close() 关闭才能监听到 'close' 事件。如果写入成功,则作为 write()/end() 的第 2 个参数传入的回调的 err 就为 undefined

可读流还有另外一些事件,比如文件打开时的 'open' 事件,当 close()end() 被调用后文件写入完成的 'finish' 事件。

可读流与可写流的连接

可读流与可写流可以通过 pipe 方法进行连接,实现对文件的复制:

const readableStream = fs.createReadStream('./test.txt')const writableStream = fs.createWriteStream('./copy.txt')readableStream.pipe(writableStream)

如此,便能将 ./test.txt 内的文本复制到 ./copy.txt 中。

更多node相关知识,请访问:nodejs 教程!

以上就是一文聊聊Node中的stream(流)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/543317.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月9日 16:17:24
下一篇 2025年11月9日 16:18:50

相关推荐

  • Golang如何在MacOS中安装Homebrew依赖

    先安装Homebrew并验证版本;2. 用brew install安装Git、Node.js、Redis、protobuf、delve等Go开发常用工具;3. 可选通过brew安装Go或指定版本;4. 定期brew update upgrade并cleanup清理。 在 macOS 上使用 Go(G…

    2025年12月16日
    000
  • CI/CD流水线搭建与自动化实践

    CI/CD通过自动化构建、测试、部署提升软件交付效率与质量,需结合版本控制、CI/CD平台、构建%ignore_a_1%等组件;以GitHub Actions为例,通过YAML配置流水线阶段,实现代码提交触发、自动化测试、质量检查与环境部署,并借助变量、缓存、条件判断提升可维护性;落地时应注重测试覆…

    2025年12月16日
    000
  • Go TCP Socket即时发送:SetNoDelay的实践与调试

    本文深入探讨go tcp客户端在设置setnodelay(true)后仍出现数据延迟发送的问题。通过分析nagle算法、服务器端处理逻辑及消息完整性,提供客户端与一个简单回显服务器的示例代码,旨在帮助开发者理解并解决tcp即时数据传输中的常见挑战,确保数据按预期立即发送和接收。 深入理解TCP数据传…

    2025年12月16日
    000
  • 如何在Golang中使用指针实现链表

    答案:在Golang中通过结构体和指针定义链表节点,包含值和指向下一节点的指针;可实现节点的创建、插入、遍历与删除操作,关键在于正确处理指针链接与nil判断。 在Golang中使用指针实现链表非常直接。链表由多个节点组成,每个节点包含数据和指向下一个节点的指针。通过结构体和指针,我们可以轻松构建和操…

    2025年12月16日
    000
  • Go TCP客户端即时发送数据:SetNoDelay的实践与服务器端诊断

    本文探讨go tcp客户端在使用`setnodelay(true)`后仍无法即时发送数据的问题。核心观点是,尽管客户端配置正确,但问题往往出在服务器端对数据的处理方式。文章提供了一个简洁的go语言tcp回显服务器示例,作为诊断工具,帮助开发者验证客户端的即时发送行为,并强调了服务器端数据处理逻辑的重…

    2025年12月16日
    000
  • Golang并发模型:阻塞库是否会影响性能?

    本文旨在解答在Golang中,阻塞库是否会像在Node.js等单线程事件循环模型中一样导致性能瓶颈。答案是否定的。Golang的goroutine机制和运行时调度器能够有效地处理阻塞操作,通过自动切换或创建新的OS线程来保证程序的并发性,因此在大多数情况下,无需特别关注库是否为非阻塞实现。本文将深入…

    2025年12月16日
    000
  • Go TCP客户端数据发送延迟问题解析与调试

    本文探讨go语言tcp客户端在使用`setnodelay(true)`后,数据仍未能即时发送的问题。核心在于理解nagle算法与tcp缓冲机制,并强调通过构建一个简单的本地回显服务器来验证客户端行为的重要性。教程将提供一个go语言实现的测试服务器,帮助开发者诊断客户端数据发送延迟的根本原因,确保数据…

    2025年12月16日
    000
  • Go语言中遍历自定义类型:深入解析与替代方案

    本文深入探讨了Go语言中`range`关键字的使用限制,明确指出`range`操作符仅支持数组、数组指针、切片、字符串、映射和允许接收操作的通道。针对遍历自定义类型的需求,我们将探讨替代方案,包括实现迭代器模式和使用`for`循环配合索引或键值访问,帮助开发者灵活处理各种数据结构。 Go语言的ran…

    2025年12月16日
    000
  • 如何在Golang中优化WebSocket性能

    优化WebSocket性能需减少内存分配、提升并发与连接管理。1. 采用单写协程从通道发送消息,读协程快速转发至业务队列,避免阻塞;2. 使用bufio.Reader减少系统调用,sync.Pool复用缓冲区,json.NewEncoder直接序列化以降低GC压力;3. 设置合理读写缓冲区(4KB~…

    2025年12月16日
    000
  • 如何使用Golang在Linux上搭建多版本环境

    使用gvm或手动方式可高效管理Linux下多Go版本。1. gvm支持安装、切换和设默认版本,如gvm install/use go1.21;2. 手动解压不同版本至独立目录,并通过函数切换GOROOT和PATH;3. 执行go version验证当前版本;4. 注意依赖安装与PATH冲突,IDE需…

    2025年12月16日
    000
  • Golang 并发模型:阻塞库是否会影响性能?

    本文旨在阐明 Golang 中阻塞库的使用对并发性能的影响。与 Node.js 等单线程事件循环模型不同,Golang 利用 Goroutine 和调度器实现了高效的并发。即使 Goroutine 调用了阻塞库,Golang 也能通过 Goroutine 的自动让出或创建新的操作系统线程来保证程序的…

    2025年12月16日
    000
  • Golang 并发模型:库是否需要非阻塞?

    本文旨在阐明 Golang 并发模型中,库是否需要设计成非阻塞的问题。通过分析 Goroutine 的调度机制,解释了 Golang 如何处理阻塞操作,以及为何开发者在编写 Golang 库时,通常无需过多关注非阻塞 I/O 的实现。文章将帮助读者理解 Golang 在高并发场景下的优势,以及简化并…

    2025年12月16日
    000
  • Golang 中是否需要非阻塞库?

    本文旨在解答 Golang 中是否需要非阻塞库的问题。通过深入探讨 Goroutine 的调度机制,阐明了 Golang 如何处理阻塞操作,以及为何在大多数情况下,开发者无需过度关注库的非阻塞特性。总结来说,Golang 的并发模型能够有效管理阻塞操作,从而简化了库的开发和维护。 在讨论 Golan…

    2025年12月16日
    000
  • Go与C++互操作:使用SWIG处理std::string参数的现代化实践

    本文详细阐述了如何利用swig在go语言与c++++之间高效地传递`std::string`参数。通过采用go 1.3.3及swig 3.0.2及更高版本提供的现代化方法,特别是借助`go build`的自动化能力,并结合`const std::string&`的规范使用,可以显著简化go与…

    2025年12月16日
    000
  • 编程语言中操作符与函数的异同解析

    #%#$#%@%@%$#%$#%#%#$%@_3bf8a523aea21a3a0f6c++53b0f43429bb中操作符与函数的界定并非一成不变,而是高度依赖于语言设计。c语言中的操作符是内置且行为固定的,而c++允许通过函数重载来扩展或改变操作符的行为。go语言则明确将`new`视为普通函数而非…

    2025年12月16日
    000
  • Golang如何优化Kubernetes集群调度

    使用Golang可有效提升Kubernetes调度效率:1. 编写自定义调度器,通过client-go监听Pod事件并实现调度算法;2. 利用Scheduler Framework扩展默认调度器,开发Filter、Score等插件;3. 优化性能,采用并发调度、缓存节点信息与增量处理;4. 实现拓扑…

    2025年12月16日
    000
  • 如何在Golang中优化gRPC吞吐量

    提升gRPC吞吐量需优化并发控制、序列化、网络连接与监控。1. 服务端设置MaxConcurrentStreams并控制goroutine数量;2. 启用gzip压缩与高效IDL设计;3. 复用客户端连接,调整TCP参数与keepalive;4. 结合pprof与Prometheus定位瓶颈,持续调…

    2025年12月16日
    000
  • Golang如何引用不同版本的模块

    Go通过Modules管理依赖版本,无法直接引用同一模块多版本,但可通过replace指令替换版本、使用主版本路径隔离(如/v2)实现间接控制,结合go.mod中require和replace语句精确管理依赖。 在 Go 中管理不同版本的模块依赖,主要依靠 Go Modules 机制。你不能在同一项…

    2025年12月16日
    000
  • Golang如何实现微服务事件驱动设计

    事件驱动架构通过发布-订阅模式解耦微服务,Golang凭借高并发和轻量级Goroutine优势,结合Kafka或NATS等消息中间件,可高效实现事件生产、消费与异步处理,配合事件结构定义、版本控制、幂等性设计及监控机制,构建可靠、可扩展的微服务系统。 微服务架构中,事件驱动设计能有效解耦服务、提升系…

    2025年12月16日
    000
  • Go与C++通过SWIG集成:处理std::string参数的现代方法

    本文详细介绍了如何利用最新go和swig版本,高效地在#%#$#%@%@%$#%$#%#%#$%@_6d505fe3df0aaea8c++a28ae0d78adbd51中调用c++函数并传递`std::string`参数。核心在于采用`go build`自动化编译流程,并利用c++侧的`const …

    2025年12月16日
    000

发表回复

登录后才能评论
关注微信