node.js中的stream模块

Node.js Stream 模块详解 阅读详情

前言

node.js天生异步和事件驱动,比较适合处理I/O相关的任务,所以在处理I/O相关的操作时,可以用stream流。

流的概念

流是一种传输手段,是有顺序的,有起点和终点,它只是一个实现了一些方法的 EventEmitter 。在unix中有一个概念:‘管道’,流在实现的过程中也可被看成是一个管道一样,进行拼接数据,将一个进程的stdout输出看成下一个进程的输入stdin。.pipe()方法是流的精髓,用于数据两端的数据桥接。可以通过 require(‘stream’) 加载 Stream 基类。就会包括以下四种流的类型。

四种基本流的类型:

1、stream.Readable    可读流(需要实现_read方法,关注点在于对数据流读取的细节)
2、stream.Writable     可写流(需要实现_write方法,关注点在于对数据流写入的细节)
3、stream.Duplex        可读/写流(需要实现以上两接口,关注点为以上两接口的细节)
4、stream.Transform  继承自Duplex(需要实现_transform方法,关注点在于对数据块的处理) 

Readable 可读流

有两种模式:flowing mode流动模式和 paused mode暂停模式,流动模式下,数据会自动从来源流出,跟不老泉似的,直到来源的数据耗尽。暂停模式下,你得通过stream.read()主动去要数据,否则不会主动将数据给你。

可读流在创建时都是暂停模式。暂停模式和流动模式可以互相转换。

要从暂停模式切换到流动模式,有下面三种办法:

  1. 给“data”事件关联了一个处理器
  2. 显式调用resume()
  3. 调用pipe()将可读流桥接到一个可写流上
  4. 要从流动模式切换到暂停模式,有两种途径:
  5. 如果这个可读的流没有桥接可写流组成管道,直接调用pause()
  6. 如果这个可读的流与若干可写流组成了管道,需要移除与“data”事件关联的所有处理器,并且调用unpipe()方法断开所有管道。

需要注意的是,出于向后兼容的原因,移除“data”事件的处理器,可读流并不会自动从流动模式转换到暂停模式;还有,对于已组成管道的可读流,调用pause也不能保证这个流会转换到暂停模式。

Readable流的一些常见实例如下:

  1. 客户端的HTTP响应
  2. 服务端的HTTP请求
  3. fs读取流
  4. zlib流
  5. crypto(加密)流
  6. TCP套接字
  7. 子进程的stdout和stderr
  8. process.stdin

Readable流提供了以下事件:

  1. readable:在数据块可以从流中读取的时候发出。它对应的处理器没有参数,可以在处理器里调用read([size])方法读取数据。
  2. data:有数据可读时发出。它对应的处理器有一个参数,代表数据。如果你只想快快地读取一个流的数据,给data关联一个处理器是最方便的办法。处理器的参数是Buffer对象,如果你调用了Readable的setEncoding(encoding)方法,处理器的参数就是String对象。
  3. end:当数据被读完时发出。对应的处理器没有参数。
  4. close:当底层的资源,如文件,已关闭时发出。不是所有的Readable流都会发出这个事件。对应的处理器没有参数。
  5. error:当在接收数据中出现错误时发出。对应的处理器参数是Error的实例,它的message属性描述了错误原因,stack属性保存了发生错误时的堆栈信息。
var fs=require('fs');
var path=require('path');
var txt = path.resolve('./text.txt');//text.txt里面的内容12345678901234567890
//指定开始位置,结束位置读取文件
// 创建一个可读流
var readable=fs.createReadStream(txt,{
    encoding:'utf8',//不传默认为buffer,显示为字符串
	highWaterMark:6,//缓冲区大小
	start:6,//开始索引值
	end:12//结束索引值
});
readable.on('open',function(fd){
	console.log('打开文件成功,句柄:'+fd); // 打开文件成功,句柄:3
});
readable.on('data',function(data){
    console.log(data)
    readable.pause();//暂停读取和发射data事件
    setTimeout(function(){
        readable.resume();//恢复读取并触发data事件
    },2000);
});
readable.on('end',function(){
	console.log('读取结束');  //读取结束
});
readable.on('close',()=>{
	console.log('读取关闭');  //读取关闭
});
readable.on('error',function(err){
	console.log('读取异常,'+err); //当出现异常时触发
})

Writable streams可写流

Writable:可写流的例子包括了:

  1. HTTP requests, on the client 客户端请求
  2. HTTP responses, on the server 服务器响应
  3. fs write streams 文件
  4. zlib streams 压缩
  5. crypto streams 加密
  6. TCP sockets TCP服务器
  7. child process stdin 子进程标准输入
  8. process.stdout, process.stderr 标准输出,错误输出

注意:每次写入文件的时候并不是直接写入文件的,而是先写入缓冲区,待缓冲区写满后再写入到文件里面。缓存区的大小就是highWaterMark,默认值是16K。

let fs = require('fs');
let ws = fs.createWriteStream('./txt.txt',{
   flags:'w',
   mode:0o666,
   start:3,
   highWaterMark:3//默认是16K
});
let flag = ws.write('1');
console.log(flag);//true
flag =ws.write('2');
console.log(flag);//true
flag =ws.write('3');
console.log(flag);//false
flag =ws.write('4');
console.log(flag);//false
  1. 如果缓存区已满 ,返回false,如果缓存区未满,返回true
  2. 如果能接着写,返回true,如果不能接着写,返回false
  3. 按理说如果返回了false,就不能再往里面写了,但是如果你真写了,如果也不会丢失,会缓存在内存里。等缓存区清空之后再从内存里读出来

自定义可写流

为了实现可写流,我们需要使用流模块中的Writable构造函数。

创建一个writable流:

  1. chunk代表写进去的数据
  2. encoding字符编码
  3. callback是一个回调函数
var stream = require('stream');
var util = require('util');
util.inherits(Writer, stream.Writable);
let stock = [];
function Writer(opt) {
    stream.Writable.call(this, opt);
}
Writer.prototype._write = function(chunk, encoding, callback) {
    setTimeout(()=>{
        stock.push(chunk.toString('utf8'));
        console.log("增加: " + chunk);
        callback();
    },500)
};
var w = new Writer();
for (var i=1; i<=5; i++){
    w.write("项目:" + i, 'utf8');
}
w.end("结束写入",function(){
    console.log(stock);
});

Duplex streams可读写的流(双工流)

Duplex 流是同时实现了 Readable 和 Writable 接口的流 
双工流的可读性和可写性操作完全独立于彼此,这仅仅是将两个特性组合成一个对象

Duplex 流的实例包括了:

  1. TCP sockets
  2. zlib streams
  3. crypto streams
const Duplex = require('stream').Duplex;
const inoutStream = new Duplex({
    write(chunk, encoding, callback) {
        console.log(chunk)
        // console.log(chunk.toString());
        callback();
    },
    read(size) {
        this.push((++this.index)+'个');
        if (this.index > 3) {
            this.push(null);
        }
    }
});
// console.log(process.stdout)
inoutStream.index = 0;
process.stdin.pipe(inoutStream).pipe(process.stdout);

Transform streams转换流

转换流(Transform streams) 是一种 Duplex 流。它的输出与输入是通过某种方式关联的。和所有 Duplex 流一样,变换流同时实现了 Readable 和 Writable 接口

转换流的输出是从输入中计算出来的 
对于转换流,我们不必实现read或write的方法,我们只需要实现一个transform方法,将两者结合起来。它有write方法的意思,我们也可以用它来push数据

变换流的实例包括:

  1. zlib streams
  2. crypto streams
const {Transform} = require('stream');
const upperCase = new Transform({
    transform(chunk, encoding, callback) {
        this.push(chunk.toString().toUpperCase());
        callback();
    }
});
process.stdin.pipe(upperCase).pipe(process.stdout);

对象流:

默认情况下,流处理的数据是Buffer/String类型的值。有一个objectMode标志,我们可以设置它让流可以接受任何JavaScript对象。

const {Transform} = require('stream');
let fs = require('fs');
let rs = fs.createReadStream('./users.json');
rs.setEncoding('utf8');
let toJson = Transform({
    readableObjectMode: true,
    transform(chunk, encoding, callback) {
        this.push(JSON.parse(chunk));
        callback();
    }
});
let jsonOut = Transform({
    writableObjectMode: true,
    transform(chunk, encoding, callback) {
        console.log(chunk);
        callback();
    }
});
rs.pipe(toJson).pipe(jsonOut);

pipe管道+链式流

前者的输出是后者的输入,pipe是一种最简单直接的方法连接两个stream,内部实现了数据传递的整个过程,在开发的时候不需要关注内部数据的流动。

  1. 这个方法从可读流拉取所有数据, 并将数据写入到提供的目标中
  2. 自动管理流量,将数据的滞留量限制到一个可接受的水平,以使得不同速度的来源和目标不会淹没可用内存
  3. 默认情况下,当源数据流触发 end的时候调用end(),所以写入数据的目标不可再写。传 { end:false }作为options,可以保持目标流打开状态

下面这段代码中,服务器每收到一次请求,就会先把data.txt读入到内存中,然后再从内存取出返回给客户端。尴尬的是,如果data.txt非常的大,而每次请求都需要先把它全部存到内存,再全部取出,不仅会消耗服务器的内存,也可能造成用户等待时间过长。


var http = require('http');
var fs = require('fs')
var server = http.createServer(function (req, res) {
    fs.readFile(__dirname + '/data.txt', function (err, dat
        res.end(data);
    });
});
server.listen(8000);

HTTP请求中的request对象和response对象都是流对象,于是我们可以换一种方法:


var http = require('http');
var fs = require('fs');
 
var server = http.createServer(function (req, res) {
    let stream = fs.createReadStream(__dirname + '/data.txt');//创造可读流
    stream.pipe(res);//将可读流写入response
});
server.listen(8000);

会在脚本的运行同级目录下压缩成一个text.gz压缩包

var fs=require('fs');
var zlib=require('zlib');
var path=require('path');
var file1=path.resolve('./text.txt');
var file3=path.resolve('./text.gz');
//压缩文件
var readable1=fs.createReadStream(file1);
var writeable=fs.createWriteStream(file3);
readable1
.pipe(zlib.createGzip())
.pipe(writeable);
 
console.log('压缩文件完成');

解压压缩文件

var fs = require("fs");
var zlib = require('zlib');

// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream('./text.gz')
  .pipe(zlib.createGunzip())
  .pipe(fs.createWriteStream('text.txt'));
  
console.log("文件解压完成。");

pipe的几种应用场景

简单stream进行的pipe使用

var path = require('path');
var fs = require("fs");
var file1=path.resolve('./test.txt');
var a = process.stdin.pipe(process.stdout)
var b = process.stdin.pipe(fs.createWriteStream(file1))
var c = fs.createReadStream(file1).pipe(process.stdin)
console.log(a,b,c)
// 输出
// Socket {connecting: false, _hadError: false, _handle: Pipe, _parent: null, _host: null, …}
// WriteStream {_writableState: WritableState, writable: true, domain: null, _events: Object, _eventsCount: 5, …}
// Socket {connecting: false, _hadError: false, _handle: Pipe, _parent: null, _host: null, …}

  剩下的几种方法参考此链接:https://blog.youkuaiyun.com/vieri_32/article/details/48376547

 

Node.js的stream模块详解,Node.js的readable.pipe()方法 stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构。什么是流?流是一种抽象的数据结构。想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地到达另一个地方(比如你家的洗手池)。我们也可以把数据看成是数据流,比如你敲键盘的时候,就可以把每个字符依次连起来,看成字符流。这个流是从键盘输入到应用程序,实际上它还对应着一个名字:标准输入流(stdin)。 阅读详情

相关推荐

JavaScript流处理深入剖析:stream.js实现与应用

JavaScript流是一种高效的数据处理技术,它优化了数据在应用程序中的流动,允许开发者在处理数据时达到更高的效率。流技术在现代JavaScript应用中扮演着重要角色,尤其是在涉及到大规模数据集和频繁的网络通信场景。是社区提供的一个性能优化版本的stream实现,它旨在减少内存占用,提高处理速度。开发者在使用这个模块时,能够享受到更小的文件体积和更快的执行速度,从而改善整体应用的性能。通过pipe()方法,Node.js流的链接变得更加简单和高效。

weixin_29363791的博客 401

STM32F429网络通信避坑指南:用CubeMX搞定LAN8720+LWIP+FreeRTOS(附完整代码)

本文详细介绍了STM32F429通过CubeMX配置LAN8720+LWIP+FreeRTOS实现网络通信的避坑指南,涵盖硬件连接、CubeMX配置、LWIP优化及调试技巧,提供完整代码和实战经验,帮助开发者高效解决以太网通信中的常见问题。

weixin_26873711的博客 145

Node Stream 入门与深入

在_read方法中,可以同步调用push(data),也可以异步调用。在上面的例子中,可读流中的数据(0, 1)与可写流中的数据(‘a’, ‘b’)是隔离开的,但在Transform中可写端写入的数据经变换后会自动添加到可读端。流中维护了一个缓存,当缓存中的数据足够多时,调用read()不会引起_read()的调用,即不需要向底层请求数据。所以,如果_read异步调用push时发现缓存为空,则意味着当前数据是下一个需要的数据,且不会被read方法输出,应当在push方法中立即以data事件输出。

GJ_ia的博客 619

骗分导论 CSP、NOIP、蓝桥杯、PAT、USACO等竞赛的算法骗分技巧 轻松省三

问题来了,那么多座桥,炸一座就破坏岛屿的联系,可能性微乎其微(除非特别设计数据)。它们的价值极大,不仅能初步帮你检验程序的对错,而且,如果你不会做这道题,你就可以直接输出样例!在OI考试中最后难的题数据最后的几个,他们往往不会创造新的数据,此时就可以直接输出最后几个数据了。需要运用《骗分导论》第3章中学到的知识,先写出朴素算法,然后造一些数据,可能就会发现规律。有些时候,问题的答案可能很有特点:对于大多数情况,答案是一样的。据说,在NOIP2013中,有人最后一题不会,愤然打了个随机数,结果得了。

星卯教育-信奥教练tony 6404

224G PAM-4 通道的 PCB 和封装设计

该行业正在努力实现层厚非常低的 sub-Dk = 3 材料,以及更先进的加工,这将使封装和 PCB 中的透射电镜截止值更高。当回波损耗占主导地位时,我们基本上需要去除沿互连产生阻抗失配的任何元件,就像上面描述的更光滑的铜和更低的 Dk 值一样。第二个影响是传输线阻抗匹配在 56 GHz 范围内的非常高的频率下非常困难的主要原因之一,另一个因素是 Tx 或 Rx 封装/缓冲器中的寄生效应。由于 PCB 和封装中的长度刻度,这是 BGA 上的焊盘、过孔和球等小结构开始在输入阻抗中产生明显偏差的频率范围。

jkh920184196的博客 841

Node.js中Stream模块详解

【代码】Node.js中Stream模块详解。

橘导的博客 633

CATIA V6二次开发——如何利用CaptureToFile截屏

CaptureToFile 今天给大家分享一个很有趣的功能,如何利用CATIA自带的功能输出模型展示图? 先上方法: 方法本身并不难,只需要赋予格式及输出路径即可完成该功能。结果如下: 看到这样一张图片不禁让我陷入了沉思,怎么会这么丑???? 那么如何让这个简单的功能变得有趣,图片变得好看点呢? 第一步:背景换色 第二步:隐藏结构树 ...

WorkMan的博客 2982

NodeJs原理 - Stream(二)

对于可读流来说,push(data)时,data只能是String或Buffer类型,而消耗时data事件输出的数据都是Buffer类型。对于可写流来说,write(data)时,data只能是String或Buffer类型,_write(data)调用时传进来的data都是Buffer类型。在上面的例子中,可读流中的数据(0, 1)与可写流中的数据(’a’, ‘b’)是隔离开的,但在Transform中可写端写入的数据经变换后会自动添加到可读端。同时,又实现了_write方法,可作为下游去消耗数据。...

小王的技术库 364

Trimble RealWorks处理点云数据(一)之坐标转换

Trimble RealWorks处理点云数据之坐标转换

yilvyangguang520的博客 3619

ESP32-IDF开发实例-外部Flash与FatFs文件系统数据存取

FatFs是用于小型嵌入式系统的通用FAT / exFAT文件系统模块。FatFs模块是按照ANSI C(C89)编写的,并且与磁盘I/O层完全分开。因此,它独立于平台。它可以并入资源有限的小型微控制器中,例如8051,PIC,AVR,ARM,Z80,RX等。ESP32-IDF对FatFs提供了良好的支持。

视觉与物联智能 2917

Node.js Stream.pipeline() Method

通过流我们可以将一大块数据拆分为一小部分一点一点的流动起来,而无需一次性全部读入,在 Linux 下我们可以通过 | 符号实现,类似的在 Nodejs 的 Stream 模块中同样也为我们提供了 pipe() 方法来实现。

★【World Of Moshow 郑锴】★ 1891

使用静态库在嵌入式系统中进行开发

静态库是一种包含预编译对象代码的文件,它可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。静态库是包含预编译对象代码的文件,可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。的静态库文件,可以在嵌入式系统的应用程序中使用它了。

ZrElixir的博客 203

浏览器中的 Node.js Stream 模块兼容方案

浏览器中的 Node.js Stream 模块兼容方案 本项目 stream-browserify 是一个开源项目,旨在为浏览器提供一个兼容 Node.js 核心模块中的 Stream API 的实现。它基于 readable-stream 模块进行了扩展,以适应那些使用旧版 Node.js Stream API 的 npm 包。该项目主要使用 JavaScript 编程语言。 新手常见问题及解决...

gitblog_00247的博客 449

2026年华为od机试真题题库

OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)

面试高手的博客 19万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Node.js:Stream、模块系统

摘要:本文介绍了Node.js中的Stream流操作、模块系统及相关应用。Stream是一个抽象接口,分为可读、可写、双工和转换流类型,通过事件机制处理数据。文章演示了文件读写、管道传输和压缩解压等流操作示例。模块系统部分说明了如何创建和引用模块,包括函数模块和对象模块,并解析了模块加载优先级策略(缓存>原生>文件)。服务端模块通过require方法加载,http等原生模块优先从内置模块加载而非文件系统。

Andytoe的博客 756

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

深入理解Node.js的Stream模块:前端开发者的指南

Node.js的Stream模块为我们提供了一种强大且高效的数据处理方式,无论是处理大文件、进行网络通信,还是进行数据的转换与加密,Stream模块都能发挥重要作用。通过对可读流、可写流、双工流和转换流的深入理解,以及对其核心方法的熟练运用,我们能够更好地优化前端应用的性能,提升用户体验。希望大家在今后的前端开发中,能够充分利用Stream模块的优势,解决更多复杂的数据处理问题,不断探索和挖掘其更多的潜力。

yan1915766026的博客 1224

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Node.js系列学习之stream模块

Node.js系列学习之stream模块

小猿同学628的博客 564

Node.js三大模块,常用内置模块介绍http模块,path模块,querystring模块,events模块,fs模块,stream模块

Node.js三大模块 Node.js内置模块 常用模块 http模块 功能:创建http server服务 常用方法: 方法一:createServer() 格式http.createServer(function(request,response){})var http = require('http'); //引用http模块 var port=8080;//端口 var hos...

weixin_45058869的博客 919

Node.js stream模块所有 API 详解 + 常用 API

Node.js的stream模块是处理流式数据的核心工具,提供了高效的大文件处理能力。文章详细介绍了四大流类型(可读、可写、双工和转换流)及其核心API,包括创建、读写、转换和管道传输等操作。重点讲解了pipeline、finished等实用方法,并给出文件复制、压缩、HTTP传输等典型应用场景。最后提供了速查表,涵盖流类型、创建方法、操作工具和常用属性,建议使用pipeline进行安全流组合,Transform处理数据转换,以及PassThrough进行调试。

DeppBing的博客,全栈修炼记|记录一个开发者的进化轨迹 1492

Node.js stream模块(一)可读流

Buffer模式 fs.read读取文件数据时,我们需要先申请一个缓冲区,用于暂存从磁盘中读取到的文件数据,当磁盘中文件数据全部读取到缓冲区后,我们再从缓冲区中取出数据进行处理,这种读取文件的方式其实叫Buffer模式,即一次性读取。 但是想要实现一次性读取面临两个问题: 1、我们无法预测被读取的文件大小,即无法初始化缓冲区的大小,默认是64KB,但是无法预知是大了还是小了 2、如果我们可以预知了文件的大小,比如1G,但是我们很难一次性申请1G内存给缓冲区,因为这样会造成系统内存紧张,引发内存溢

优快云 2254

Node.js IO模块深度解析:从Buffer到Stream的完整指南

Node.js IO模块深度解析:从Buffer到Stream的完整指南 前言 在Node.js的世界中,IO(输入/输出)操作是核心能力之一。本文将从技术专家的角度,深入解析Node.js中的IO相关模块,帮助开发者全面理解其工作原理和最佳实践。 一、Node.js IO基础概念 1.1 什么是IO密集型业务 IO密集型业务是指应用程序的性能主要受限于输入/输出操作(如文件读写、网络请求等)的业...

gitblog_01153的博客 522

NodeJS Modbus Stream:一款强大的Node.js Modbus数据流处理模块

NodeJS Modbus Stream:一款强大的Node.js Modbus数据流处理模块 1. 项目基础介绍及主要编程语言 NodeJS Modbus Stream 是一个基于 Node.js 开发的开源模块,它提供了一个处理 Modbus 数据流的解决方案。该项目主要使用 JavaScript 编程语言,并包含少量的 TypeScript 代码,用于构建核心的 PDU(协议数据单元)和处理...

gitblog_00927的博客 401

Node.js基本模块stream

Node.js基本模块stream stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构。

胡杰的专栏 867

Node.js 使用Stream模块传送数据

Stream模块是Node.js一个重要模块。数据流是可读、可写或即可读又可写得内存结构。接下来介绍使用Stream模块来创建流,以及从它们中读出数据和向它们写入数据。 1 Readable流Readable流可以方便地读取从其他来源进入应用程序的数据。 Readable流公开了一些事件:- readable:在数据块可以从流中读取时发出。 - data:类似于readable,但数据的处理程序

mvpzx的博客 719

Node.js学习(6)- 数据流模块stream

1.stream是Node.js在服务端的模块,用于支持流数据结构。 stream是一种对象,对对象的处理就是响应事件,而js本身就是事件驱动:data事件表示流的数据已经可以读取了,end事件表示这个流已经到末尾了,没有数据可以读取了,error事件表示出错了。 "use strict"; var fs = require("fs"); //所有可以读取数据的流都继承自 stream...

程序员精进之路 567
上一篇: node.js中的module模块
下一篇: node.js中fs模块+path模块
晶球
博客等级 码龄9年 4粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值