当前位置: 首页 > news >正文

readline模块详解!!【Node.js】

‌“书到用时方恨少,事非经过不知难。”‌ —— 陆游

目录

  • ‌readline 是什么?
  • ‌基本用法:
    • ‌创建 Interface 类:
    • 核心流程‌:
  • ‌Interface 类的关键事件:
    • line:
    • close:
    • pause:
    • resume:
    • prompt:
  • 关键事件表格展示:

‌readline 是什么?

readline 是 Node.js 内置的核心模块,用于‌逐行处理输入/输出流‌(如文件、命令行输入),通过事件驱动机制实现非阻塞式行级数据处理‌。它适用于需要交互式逐行读取的场景(如命令行工具、日志解析等)。

‌基本用法:

‌创建 Interface 类:

通过 readline.createInterface() 方法创建接口实例,每个实例都关联一个input可读流和一个outpu可写流,绑定输入/输出流‌。

const readline = require('readline');
const rl = readline.createInterface({input: process.stdin, // 输入流(如文件流、标准输入)output: process.stdout // 输出流(如标准输出)
});

核心流程‌:

  • 绑定输入流‌:如 fs.createReadStream(‘file.txt’) 读取文件‌;‌
  • 逐行处理‌:通过事件监听逐行获取数据;
  • 关闭接口‌:完成操作后调用 rl.close() 释放资源‌

‌Interface 类的关键事件:

line:

此事件在输入流(例如文件流或标准输入)检测到换行符(\n,\r\r\n时触发line事件,即用户按下<Enter> 键或 )时即刻触发,意味着我们可以借此机会对每一行输入数据进行实时处理。

设想有一个名为 example.txt 的文本文件,内容如下:

第一行内容
第二行内容
第三行内容

我们的目标是逐行读取这个文件,并将每行的内容打印到控制台。

实现步骤:

  • ‌引入所需模块‌:首先,需要引入 Node.js 的 fs(文件系统)模块和 readline 模块。
  • 创建文件读取流‌:利用 fs.createReadStream 方法,我们可以创建一个指向 example.txt 文件的读取流。‌
  • 构建 Interface 实例‌:接着,需要用这个读取流作为输入,来创建一个 readline.Interface 实例。
  • 监听 line 事件‌:为 Interface 实例绑定一个 line 事件监听器,这样每当读取到一行新数据时,该监听器就会被触发,并接收到这行数据作为参数。
  • 处理数据‌:在 line 事件的回调函数中,可以对接收到的行数据进行处理,本例中即将其打印到控制台。
  • 关闭接口‌(可选):虽然对于文件读取来说不是必需的,但在处理完所有行后关闭 Interface 实例是一个好习惯。

示例代码:

const fs = require('fs');
const readline = require('readline');// 创建一个指向 example.txt 文件的读取流
const fileStream = fs.createReadStream('example.txt');// 利用文件读取流构建一个 readline.Interface 实例
const rl = readline.createInterface({input: fileStream,crlfDelay: Infinity // 确保兼容不同系统的换行符
});// 监听 line 事件,逐行处理文件内容
rl.on('line', (line) => {console.log(line); // 将读取到的行内容打印到控制台
});// 监听 close 事件,以便在所有行处理完毕后执行清理操作(本例中无需特别处理)
rl.on('close', () => {console.log('文件读取完成。');
});

close:

close事件在 Interface 实例被关闭时触发。这通常发生在所有输入数据都已经被处理完毕,且不再需要该接口时。 它可以释放与接口相关联的资源,并确保不会有未处理的事件或回调函数残留。

close 事件的触发时机:

  • 当显式调用 rl.close() 方法时,close 事件会被触发。
  • 如果输入流(如文件流)自然结束(例如,文件被完全读取),并且没有更多的数据可以读取,那么 Interface 会自动关闭,并触发 close 事件。
  • 在某些情况下,如遇到错误或异常导致接口无法继续工作时,Interface 也可能会自动关闭,并触发 close 事件。

close 事件的处理:
在 close 事件的回调函数中,可以执行任何需要在接口关闭时进行的清理操作。这可能包括关闭文件描述符、释放内存、结束数据库连接、发送通知等。

示例代码:
以下是一个包含 close 事件处理的示例代码,它读取一个文件并在处理完所有行后自动关闭接口。

const fs = require('fs');
const readline = require('readline');// 创建一个指向文件的读取流
const fileStream = fs.createReadStream('example.txt');// 构建 readline.Interface 实例
const rl = readline.createInterface({input: fileStream,crlfDelay: Infinity // 兼容不同系统的换行符
});// 监听 line 事件,逐行处理文件内容
rl.on('line', (line) => {console.log(line); // 打印读取到的行内容
});// 监听 close 事件,执行清理操作
rl.on('close', () => {console.log('文件已完全读取,接口已关闭。');// 在这里执行任何需要的清理操作
});// 注意:对于文件流,通常不需要显式调用 rl.close(),
// 因为当文件读取完毕时,流会自动结束,从而触发 close 事件。

pause:

pause 事件是 readline 模块中的一个事件,它在用户按下 Ctrl+S 组合键时被触发,用于暂停终端的输出‌。不过,需要注意的是,readline 默认情况下并不会直接处理这个 pause 事件来暂停输入流,而是会暂停终端的输出显示。 这意味着,尽管 pause 事件被触发了,但输入流本身可能仍然会继续接收数据,只是这些数据暂时不会在终端上显示出来。

为了正确处理 pause 事件并暂停输入流,我们可以采取以下步骤:

  • 使用 readline.createInterface 方法创建一个 readline.Interface 实例。
  • 监听 pause 事件,并在事件处理程序中调用 rl.pause() 方法来手动暂停输入流(尽管这通常不是必需的,因为 pause 事件本身并不会自动暂停输入流,但我们可以在这里执行其他与暂停相关的逻辑)。

‌手动暂停和恢复输入流的示例‌:

const readline = require('readline');
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});// 监听 pause 事件(尽管它通常不会直接暂停输入流)
rl.on('pause', () => {console.log('pause 事件被触发,但输入流不会自动暂停。');// 你可以在这里执行其他逻辑,比如显示一个提示信息
});// 手动暂停输入流(如果需要)
// rl.pause(); // 这行代码会在调用时暂停输入流,直到你调用 rl.resume()// 监听其他事件,如 line 事件来处理输入数据
rl.on('line', (line) => {console.log(`接收到输入: ${line}`);// 根据需要处理输入数据
});// 在适当的时候关闭接口
// rl.close(); // 这行代码会在你准备好关闭接口时调用

resume:

在 readline 模块中,resume 事件是一个与 pause 事件相对应的事件,它用于指示输入流已经被恢复。 当输入流处于暂停状态时,如果用户执行了某些操作(比如按下 Ctrl+Q 组合键,这取决于终端和操作系统的具体行为),或者在代码中显式调用了 rl.resume() 方法,resume 事件就会被触发。

resume 事件的触发时机:

  • 当之前被暂停的输入流被恢复时,resume 事件会被触发。
  • 这通常发生在用户按下 Ctrl+Q 组合键(在大多数终端和操作系统中,Ctrl+S 用于暂停输出,Ctrl+Q 用于恢复输出,但请注意这可能会因环境而异)或者在代码中调用了 rl.resume() 方法之后。

resume 事件的处理:
在 resume 事件的回调函数中,我们可以执行任何需要在输入流恢复时进行的操作。这可能包括更新用户界面、恢复数据处理逻辑等。

const readline = require('readline');
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});// 监听 resume 事件
rl.on('resume', () => {console.log('输入流已恢复。');// 在这里执行任何需要在输入流恢复时进行的操作
});// 监听 pause 事件(尽管它通常不会直接暂停输入流,但可以作为用户操作的指示)
rl.on('pause', () => {console.log('输入流已暂停(注意:这通常是由 Ctrl+S 触发的,但 readline 默认不会直接暂停输入流)。');// 你可以在这里执行其他逻辑,比如显示一个提示信息// 如果需要,你也可以显式调用 rl.pause() 来暂停输入流,但通常这不是必需的
});// 监听 line 事件来处理输入数据
rl.on('line', (line) => {console.log(`接收到输入: ${line}`);// 根据需要处理输入数据
});// 在适当的时候关闭接口
// rl.close(); // 这行代码会在你准备好关闭接口时调用// 注意:在这个示例中,我们没有显式调用 rl.pause() 来暂停输入流,
// 因为 readline 默认不会将 Ctrl+S 解释为暂停输入流的命令。
// 如果你想测试 resume 事件,你可能需要在其他上下文中暂停输入流,
// 或者使用其他方法来模拟输入流的暂停和恢复。

需要注意的是,readline 模块默认不会将 Ctrl+S 和 Ctrl+Q 组合键解释为暂停和恢复输入流的命令。这些组合键通常用于控制终端输出的暂停和恢复。如果你希望在代码中显式控制输入流的暂停和恢复,你应该使用 rl.pause() 和 rl.resume() 方法。

prompt:

用于在终端中显示提示符,并准备接收用户输入。
rl.prompt([preserveCursorPosition]) 方法会向用户显示一个可配置的提示符(通常是一个字符串,如 > ),并将输入光标移动到提示符之后,等待用户输入。这个方法不会触发一个事件,而是直接作为一个命令来执行。

const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout,prompt: 'MyPrompt> ' // 设置自定义提示符
});// 监听 line 事件来处理用户输入
rl.on('line', (input) => {console.log(`你输入了: ${input}`);// 再次显示提示符以等待下一次输入rl.prompt();
});// 显示提示符以开始接收输入
rl.prompt();

关键事件表格展示:

‌事件名称触发条件用途
line输入流接收到换行符(如回车键)时触发处理单行数据(如解析内容、执行逻辑)‌
close接口关闭时触发(调用 rl.close() 后)执行清理操作(如释放资源、结束进程)
pause输入流暂停时触发处理暂停状态(如缓冲控制)
resume输入流恢复时触发处理恢复后的逻辑
prompt在终端中显示提示符接收用户输入
SIGINT用户按下 Ctrl+C 时触发自定义中断行为(如安全退出)

相关文章:

readline模块详解!!【Node.js】

‌“书到用时方恨少&#xff0c;事非经过不知难。”‌ —— 陆游 目录 ‌readline 是什么&#xff1f;‌基本用法&#xff1a;‌创建 Interface 类&#xff1a;核心流程‌&#xff1a; ‌Interface 类的关键事件&#xff1a;line&#xff1a;close&#xff1a;pause&#xff1a…...

软件测试的七大误区

随着软件测试对提高软件质量重要性的不断提高&#xff0c;软件测试也不断受到重视。但是&#xff0c;国内软件测试过程的不规范&#xff0c;重视开发和轻视测试的现象依旧存在。因此&#xff0c;对于软件测试的重要性、测试方法和测试过程等方面都存在很多不恰当的认识&#xf…...

【欢迎来到Git世界】Github入门

241227 241227 241227 Hello World 参考&#xff1a;Hello World - GitHub 文档. 1.创建存储库 r e p o s i t o r y repository repository&#xff08;含README.md&#xff09; 仓库名需与用户名一致。 选择公共。 选择使用Readme初始化此仓库。 2.何时用分支&#xf…...

解决 Ubuntu 24.04 虚拟机内无法ping 通 Hostname 的问题

问题背景 在 VMware 或 VirtualBox 中安装 Ubuntu 24.04 虚拟机时&#xff0c;遇到无法通过主机名&#xff08;Hostname&#xff09;进行网络通信的问题。例如&#xff0c;将虚拟机的主机名设置为 001&#xff0c;执行 ping 001 时返回 ping 0.0.0.1 并超时。此问题通常由 主机…...

给小白的oracle优化工具,了解一下

有时懒得分析或语句太长&#xff0c;可以尝试用oracle的dbms_sqldiag包进行sql优化&#xff0c; --How To Use DBMS_SQLDIAG To Diagnose Query Performance Issues (Doc ID 1386802.1) --诊断SQL 性能 SET ECHO ON SET LINESIZE 132 SET PAGESIZE 999 SET LONG 999999 SET SER…...

CT技术变迁史——CT是如何诞生的?

第一代CT(平移-旋转) X线球管为固定阳极,发射X线为直线笔形束,一个探测器,采用直线和旋转扫描相结合,即直线扫描后,旋转1次,再行直线扫描,旋转180完成一层面扫描,扫描时间3~6分钟。矩阵象素256256或320320。仅用于颅脑检查。 第二代CT (平移-旋转) 与第一代无质…...

【PHP脚本语言详解】为什么直接访问PHP文件会显示空白?从错误示例到正确执行!

前言 作为一名开发者&#xff0c;你是否曾经遇到过这样的问题&#xff1a;写了一个PHP脚本&#xff0c;放到服务器根目录后&#xff0c;直接通过file:///路径访问却显示空白页面&#xff1f;而换成http://localhost却能正常显示&#xff1f;这篇文章将带你深入理解PHP脚本语言…...

软件工程---需求工程

软件需求工程师发现、获取、组织、分析、编写和管理需求的系统方法&#xff0c;以使客户和项目组之间达成共识。 需求工程共包含五个步骤&#xff1a; 需求获取&#xff1a;对业务问题分析&#xff0c;与项目干系人沟通&#xff0c;以理解系统的目标、期望和约束&#xff0c;…...

spring注解开发(Spring整合MyBatis——Mapper代理开发模式、(Spring、MyBatis、Jdbc)配置类)(6)

目录 一、纯MyBatis独立开发程序。 &#xff08;1&#xff09;数据库与数据表。 &#xff08;2&#xff09;实体类。 &#xff08;3&#xff09;dao层接口。&#xff08;Mapper代理模式、无SQL映射文件——注解配置映射关系&#xff09; &#xff08;4&#xff09;MyBatis核心配…...

散户情绪周期模型(情绪影响操作)

目录 一、个股上涨阶段情绪演化二、个股下跌阶段情绪演化三、底部震荡阶段情绪演化四、情绪观察与操作工具箱1. 情绪自测量表&#xff08;每日收盘后记录&#xff09;2. 情绪-指标对照表 五、高阶情绪管理技巧1.认知重构训练2.生理指标监控&#xff08;需配合智能手表&#xff…...

计算机毕业设计SpringBoot+Vue.js网上商城系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

自动化测试无法启动(java.net.SocketException)

在运行测试代码,对浏览器进行自动化操作时,遇到了以下问题,添加依赖,编写了测试代码,但是程序无法运行 这个有两种原因(我使用的是谷歌浏览器): 网络问题: 因为需要从GitHub上下载对应包,所以有时候可能会出现网络问题,这个时候可以打开VPN之后,重新对程序进行启动 浏览器版本…...

智能机器人加速进化:AI大模型与传感器的双重buff加成

Deepseek不仅可以在手机里为你解答现在的困惑、占卜未来的可能&#xff0c;也将成为你的贴心生活帮手&#xff01; 2月21日&#xff0c;追觅科技旗下Dreamehome APP正式接入DeepSeek-R1大模型&#xff0c;2月24日发布的追觅S50系列扫地机器人也成为市面上首批搭载DeepSeek-R1的…...

osgEarth安装总结

第一步&#xff1a;安装OSG 直接通过git下载源码&#xff0c;使用cmake进行编译&#xff0c; git clone --depth 1 https://github.com/openscenegraph/OpenSceneGraph.git mkdir build cd build cmake .. make sudo make isntall编译过程中缺什么库&#xff0c;就安装什么库 …...

Java多线程与高并发专题——从AQS到ReentrantLock

关于AQS AQS就是AbstractQueuedSynchronizer抽象类&#xff0c;AQS其实就是JUC包下的一个基类&#xff0c;JUC下的很多内容都是基于AQS实现了部分功能&#xff0c;比如ReentrantLock&#xff0c;ThreadPoolExecutor&#xff0c;阻塞队列&#xff0c;CountDownLatch&#xff0c…...

力扣 寻找重复数

二分&#xff0c;双指针&#xff0c;环形链表。 题目 不看完题就是排序后&#xff0c;用两个快慢指针移动&#xff0c;找到相同就返回即可。 class Solution {public int findDuplicate(int[] nums) {Arrays.sort(nums);int l0;int r1;while(r<nums.length){if(nums[l]num…...

第48天:Web开发-JavaEE应用依赖项Log4j日志Shiro验证FastJson数据XStream格式

#知识点 1、安全开发-JavaEE-第三方依赖开发安全 2、安全开发-JavaEE-数据转换&FastJson&XStream 3、安全开发-JavaEE-Shiro身份验证&Log4j日志处理 一、Log4j 一个基于Java的日志记录工具&#xff0c;当前被广泛应用于业务系统开发&#xff0c;开发者可以利用该工…...

ES6笔记总结

首先我们需要了解一下什么是 ECMA&#xff1a; ECMA&#xff08;European Computer Manufacturers Association&#xff09;中文名称为欧洲计算机制造商协会&#xff0c;这 个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际 什么是 ECMAScr…...

使用Docker Desktop部署GitLab

1. 环境准备 确保Windows 10/11系统支持虚拟化技术&#xff08;需在BIOS中开启Intel VT-x/AMD-V&#xff09;内存建议≥8GB&#xff0c;存储空间≥100GB 2. 安装Docker Desktop 访问Docker官网下载安装包安装时勾选"Use WSL 2 instead of Hyper-V"&#xff08;推荐…...

经典算法 统计数字问题(常数时间解决)

统计数字问题 一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排&#xff0c;每个页码都不含多余的前导数字0。例如&#xff0c;第6 页用数字6 表示&#xff0c;而不是06 或006 等。数字计数问题要求对给定书的总页码n&#xff0c;计算出书的全部页…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...