nodeJs常用的内置模块 url querystring http path events fs ctypto stream zlib

nodeJs中常用的一些内置模块有:

  • url,用于处理与解析 URL;
  • querystring,用于解析和格式化 URL 查询字符串;
  • http,HTTP服务;
  • path,路径,用于处理文件路径和目录路径;
  • events,事件触发器,用于事件的派发与监听;
  • fs,文件系统,用于文件的读写操作;
  • ctypto,用于数据的加密和解密;
  • stream,流
  • zlib,压缩

1.url URL操作

1.1 new URL()

new URL(urlString,base),如果 urlString 是相对路径,则需要 base。 如果 urlString 是绝对路径,则忽略 base。它的部分属性如下:

  • hostname,获取及设置 URL 的主机名部分,它和host的区别是,它不包含端口。
  • pathname,获取及设置 URL 的路径部分,也就是端口号后面的所有内容。
  • port,获取及设置 URL 的端口部分。http协议的默认端口号是80,https协议的默认端口号是443。ftp协议的默认端口号是21
  • search,获取及设置 URL 的序列化查询部分。也就是 ?号后面的所有内容,包含?号。
const myURL = new URL('https://example.org:8088/abc/foo#bar');
console.log(myURL.hash); //#bar
console.log(myURL.hostname); //example.org
console.log(myURL.pathname); //abc/foo#bar

const searchURL = new URL('https://example.org/abc?123');
console.log(searchURL.search); //?123
searchURL.search = 'abc=xyz';
console.log(searchURL.href); //https://example.org/abc?abc=xyz

在http请求中,可以使用new URL()来获取想要的数据:

  • 第一个参数相当于request.url
  • 第二个参数相当于request.headers.host
let url=new URL("/user?name=haha&age=18", "http://localhost:8088");
//"/user?name=haha&age=18"相当于request.url
//"http://localhost:8088"相当于request.headers.host
console.log(url);

打印结果如下:
nodeJs常用的内置模块 url querystring http path events fs ctypto stream zlib_第1张图片

1.2 url.parse()

解析传进来的路径。

语法:url.parse(urlString, parseQueryString, slashesDenoteHost)

  • urlString,url地址字符串。
  • parseQueryString,布尔值,表示是否将url的query解析为js对象,默认为false,设置为true后,可以通过query属性获取参数对象
  • slashesDenoteHost,布尔值,如果为真,那么字符串//之后的第一个令牌和下一个/之前的第一个令牌将被解释为主机。例如,给定//foo/bar,结果应该是{host: ‘foo’, pathname: ‘/bar’}而不是{pathname: ‘//foo/bar’}。默认值:false。

详细内容如下图:
nodeJs常用的内置模块 url querystring http path events fs ctypto stream zlib_第2张图片

1.3 url.format(urlObject)

将传入的url对象,拼接成Url路径字符串;

const url = require('url');
var params = {
    protocol: 'https:',
    hostname: 'www.lagou.com',
    port: '8080',
    pathname: '/a',
    search: '?name=zhangsan&age=20',
    hash: '#position',
  }
  
console.log(url.format(params));
//https://www.lagou.com:8080/a?name=zhangsan&age=20#position

1.4 url.resolve(from, to)

拼接url路径,按照第一个参数的目录路径来拼接,类似于path的resolve();

const url = require('url');
url.resolve('/one/two/three', 'four');
// '/one/two/four'
url.resolve('http://example.com/', '/one');
// 'http://example.com/one'
url.resolve('http://example.com/one', '/two');
// 'http://example.com/two'

2. querystring 解析查询字符串

2.1 escape和unescape

  • querystring.escape(str),对给定的 str 执行 URL 百分比编码,通常不会直接使用,直接使用querystring.stringify();
  • querystring.unescape(str),对给定的 str 上执行 URL 百分比编码字符的解码,通常不会直接使用,直接使用querystring.parse();默认使用 JavaScript 内置的 decodeURIComponent() 方法进行解码;
const qs = require('querystring');
var strUrl = 'https://www.baidu.com/s?key=前端&date=0317';
var tmp = qs.escape(strUrl);
console.log(tmp);
//https%3A%2F%2Fwww.baidu.com%2Fs%3Fkey%3D%E5%89%8D%E7%AB%AF%26date%3D0317
console.log(qs.unescape(tmp));
//https://www.baidu.com/s?key=前端&date=0317

2.2 querystring.parse()

querystring.parse(str, sep, eq, options)将 URL 查询字符串 str 解析为键值对的集合。

  • str,要解析的 URL 查询字符串。
  • sep,用于在查询字符串中分隔键值对的子字符串。默认值: ‘&’。
  • eq,用于在查询字符串中分隔键和值的子字符串。默认值: ‘=’。
const qs = require('querystring');
var myUrl=new URL('https://www.baidu.com/s?key=前端&date=0317');
var searchStr=myUrl.search.substring(1);
console.log(qs.parse(searchStr));
//{ key: '前端', date: '0317' }

2.3 querystring.stringify()

querystring.stringify(obj, sep, eq, options)将传入的对象拼接成字符串。

  • obj,要序列化为 URL 查询字符串的对象。
  • sep,对象与对象之间的连接符。默认值: ‘&’。
  • eq,key和value之间的连接符。默认值: ‘=’。
const qs = require('querystring');
var params = {
  name: 'wangh',
  age: 20
}
console.log(qs.stringify(params));
//name=wangh&age=20
console.log(qs.stringify(params, '#', '^'));
//name^wangh#age^20

3. http 请求

3.1 http.get()

由于大多数请求都是没有主体的 GET 请求,因此 Node.js 提供了这个便捷的方法。 这个方法与 http.request() 的唯一区别是它将方法设置为 GET 并自动调用 req.end()。

  • 语法:http.get(url,callback)
  • callback 调用时只有一个参数,为服务端返回的数据。
  • 如果请求失败,需要执行res.resume();来释放内存。
const http=require("http");
http.get('http://localhost:3000', (res) => {
	res; //服务端返回的响应数据
	res.statusCode; //响应的状态码
    res.headers; //响应的消息头对象。
    if(请求失败) res.resume();
}

3.2 http.request()

  • 语法:http.request(url, options, callback)
  • 一般用来发送POST请求。
  • http.request() 返回 http.ClientRequest 类的实例,可以链式调用。
  • 如果同时指定了 url 和 options,则对象会被合并,其中 options 属性优先。
  • 必须调用 req.end()来表示请求的结束,
const options = {
	hostname: 'localhost',
	port: 80,
	path: '/upload',
	method: 'POST',//GET 或者 POST,大写
	headers: {//请求头信息}
};
const clientReq = http.request(options, (res) => {
	res; //服务端返回的响应数据
});
//请求遇到问题
clientReq.on('error', (e) => {
	console.error(`请求遇到问题: ${e.message}`);
});
//发送请求
clientReq.write(postData);
//请求结束
clientReq.end();

3.3 http.createServer()

创建服务,http.createServer()返回新的 http.Server 实例。

const http = require('http')
var app = http.createServer((request, response) => {
	request.method; //判断是GET请求还是POST请求
	request.url; //路径端口号后面的内容
	request.header; //请求头内容
	request.on("data",()=>{}); //收到客户端发来的数据
    request.on("end",()=>{  //数据接收完毕
	    response.setHeader(); //设置响应头内容
		response.write(str); //发送数据给客户端
		response.end(); //响应完毕
    }); 
})
app.listen(3000, () => {	//开启服务
	console.log('localtion start 3000')
})

3.3.1 setHeader和writeHead

  • response.setHeader(name, value)

    • 为隐式响应头设置单个响应头的值。 如果此响应头已存在于待发送的响应头中,则其值将被替换。
  • response.writeHead(statusCode, headers)

    • 状态码是一个 3 位的 HTTP 状态码,如 404。
    • 只能在消息上调用一次,并且必须在 response.end() 之前调用
    • 将提供的响应头值写入网络通道而不在内部进行缓存。
  • 当使用 response.setHeader() 设置响应头时,它们将与传给 response.writeHead() 的任何响应头合并,其中 response.writeHead() 的响应头优先

  • response.getHeader() 只能获取到 setHeader() 的内容。

// 返回 content-type = text/plain
const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});

4. path 路径

用于处理文件路径和目录路径。

4.1 path.dirname()

该方法返回 path 的目录名,类似于 Unix 的 dirname 命令。

path.dirname('/foo/bar/baz/asdf/quux');
// 返回: '/foo/bar/baz/asdf'

4.2 path.extname()

该方法返回 path 的扩展名。

path.extname('index.html');
// 返回: '.html'
path.extname('.index.md');
// 返回: '.md'

4.3 path.parse()

该方法返回一个对象,其属性表示 path 的重要元素。 尾部的目录分隔符将被忽略。
nodeJs常用的内置模块 url querystring http path events fs ctypto stream zlib_第3张图片

path.parse('/home/user/dir/file.txt');
// 返回:
// { root: '/',
//   dir: '/home/user/dir',
//   base: 'file.txt',
//   ext: '.txt',
//   name: 'file' }

4.4 path.resolve()

  • 该方法将路径或路径片段的序列解析为绝对路径。
  • 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则再加上当前工作目录。
  • 生成的路径已规范化,并且除非将路径解析为根目录,否则将删除尾部斜杠。
  • 如果没有传入 path 片段,则 path.resolve() 将返回当前工作目录的绝对路径。
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'
path.resolve('/foo/bar', '../baz');
// 返回: '/foo/baz'
path.resolve('/foo/bar', '/tmp/file/');
// 返回: '/tmp/file'

5. events 事件触发器

  • 所有能触发事件的对象都是 EventEmitter 类的实例。 这些对象有一个 eventEmitter.on() 函数,用于将一个或多个函数绑定到命名事件上。事件的命名通常是驼峰式的字符串。
  • eventEmitter.emit(),用于抛发/派发事件。
  • eventEmitter.on(),用于侦听事件,可以传任意数量的参数到监听器函数。
  • eventEmitter.once(),表示事件只被侦听一次。 当事件被触发时,监听器会被注销。
  • 当监听器函数被调用时, this 关键词会被指向监听器所绑定的 EventEmitter 实例。
const eventEmitter = require('events');
class MyEventEmitter extends eventEmitter { }
const em = new MyEventEmitter();
em.on('event', function () {
  console.log('触发事件', arguments);
})
em.emit('event', 'aa','bb','cc');
//打印结果:触发事件 [Arguments] { '0': 'aa', '1': 'bb', '2': 'cc' }

5.1 自定义事件

var Events = {
	listens: {},
	on: function (eventName, cb) {
		if (this.listens[eventName]) {
			this.listens[eventName].push(cb);
		} else {
			this.listens[eventName] = [cb];
		}
	},
	trigger: function (eventname) {
		let evt.currentTarget = this;
		for (let i = 0; i < this.listens[eventname].length; i++) {
			this.listens[eventname][i].call(evt.currentTarget);
		}
	}
}
Events.on('event', () => {
	console.log('触发事件');
})
Events.trigger('event');

6. fs 文件系统

  • 模仿标准 POSIX 函数的方式与文件系统进行交互,例如文件的新建、编辑、删除等。
  • 所有文件系统操作都具有同步和异步两种形式。
  • 建议使用异步的形式,因为同步的形式会阻塞整个进程。
  • 异步形式中最后一个参数为回调函数。根据nodejs 中错误优先的原则,回调函数中第一个参数为err,如果操作成功完成,则err 为 null 或 undefined。
const fs = require('fs');

fs.unlink('/tmp/hello', (err) => {
  if (err) throw err; //throw 抛出异常
  console.log('已成功删除 /tmp/hello');
});

6.1 fs.writeFile() 创建文件

  • fs.writeFile(path,content,cb),创建一个文件,是一个异步操作,必须有回调函数。
  • fs.writeFileSync(path,content) ,创建一个文件,是一个同步操作。
  • 第一个参数path为文件名称,第二个参数content为文件的内容,可以是字符串或 buffer格式,第三个参数cb为回调函数。
  • 如果文件已经存在,重复创建,会覆盖里面的内容。
let fs = require("fs");
//创建一个a.txt,并写入内容 hello!!
fs.writeFile("./a.txt","hello!!",(err)=>{
    if(err) throw err;
})

6.2 fs.readFile() 读取文件内容

  • fs.readFile(path,options,cb),读取文件的全部内容,是一个异步操作,必须有回调函数。
  • fs.readFileSync(path),读取文件的全部内容,是一个同步操作。
  • 第一个参数path为文件名称,第二个参数可以设置读取出来的文件内容的编码规则,第三个参数cb为回调函数。
  • 如果没有指定文件内容的编码规则,则返回原始的 buffer。
  • 回调函数中会传入两个参数 (err, data),其中 data 是文件的内容。
//a.txt文件
{"name":"张三"}

//js文件
let fs = require("fs");
fs.readFile("./a.txt",(err,data)=>{
    if(err) throw err;
    console.log(data); //
})
fs.readFile("./a.txt","utf-8",(err,data)=>{
    if(err) throw err;
    console.log(data); //{"name":"张三"}
})

6.3 fs.unlink() 删除文件

  • fs.unlink(path,cb),删除文件,是一个异步的操作,必须有回调函数。
  • fs.unlinkSync(path),删除文件,是一个同步的操作。
  • 第一个参数path为文件名称,第二个参数cb为回调函数。
  • fs.unlink() 不能用于删除目录。 要删除目录,需要使用 fs.rmdir()
let fs = require("fs");
// 假设 'path/file.txt' 是常规文件。
fs.unlink('path/file.txt', (err) => {
  if (err) throw err;
  console.log('文件已删除');
});

6.4 fs.appendFile() 在文件中追加内容

  • fs.appendFile(path,content,cb),在文件中追加内容,是一个异步操作,必须有回调函数。
  • fs.appendFileSync(path,content),在文件中追加内容,是一个同步操作。
  • 第一个参数path为文件名称,第二个参数content为要追加的内容,可以是字符串或 buffer格式,第三个参数cb为回调函数。
  • 如果文件尚不存在,则会创建该文件。
let fs = require("fs");
// 在aa.txt中追加内容
fs.appendFile('aa.txt', 'my name is haha', (err) => {
  if (err) throw err;
  console.log('数据已追加到文件');
});

6.5 fs.mkdir() 创建目录

  • fs.mkdir(path,options,cb),创建文件夹,是一个异步操作,必须有回调函数。
  • fs.mkdirSync(path),创建文件夹,是一个同步操作。
  • 第一个参数path为文件夹名称,第二个参数可以设置是否要创建父文件夹,第三个参数cb为回调函数。
  • 第二个参数 options中recursive 表示是否要创建父文件夹,默认为false。
  • 文件夹重复创建,会报错
let fs = require("fs");

//会报错,Error: ENOENT: no such file or directory, mkdir './tmp1/a/apple'
fs.mkdir('./tmp1/a/apple', (err) => {
  if (err) throw err;
});

//在项目的根目录下创建了tmp2->a->apple,一共3个文件夹
fs.mkdir('./tmp2/a/apple', { recursive: true }, (err) => {
  if (err) throw err;
});
//文件夹重复创建,会报错
//Error: EEXIST: file already exists, mkdir './tmp2/a/apple'

6.6 fs.readdir() 读取目录的内容

  • fs.readdir(path,cb),读取目录的内容,是一个异步操作,必须有回调函数。
  • fs.readdirSync(path),读取目录的内容,是一个同步操作。
  • 第一个参数path为文件夹名称,第二个参数cb为回调函数。
  • 回调函数中有两个参数 (err, files),其中 files 是目录中的文件名的数组(不包括 ‘.’ 和 ‘…’)。
  • 如果是同步操作,则fs.readdirSync(path)返回目录中的文件名的数组。
let fs = require("fs");
//tmp文件夹下有a目录和text.txt文件
let path="./tmp"

fs.readdir(path,(err,files)=>{
	console.log(files); //['a','text.txt']
})

console.log(fs.readdirSync(path)); //['a','text.txt']

6.7 fs.rmdir() 删除目录

  • fs.rmdir(path,cb),删除目录,是一个异步操作,必须有回调函数。
  • fs.rmdirSync(path),删除目录,是一个同步操作。
  • 第一个参数path为文件夹名称,第二个参数cb为回调函数。
  • 只能删除空的目录,如果该目录里有内容,则会报错。

案例:传入文件名或者目录名,删除该文件或者该目录下所有的内容:

let fs = require("fs");
function removeFile(path){
	//如果传进来的是文件,则直接删除并跳出
	if(fs.statSync(path).isFile()) return fs.unlinkSync(path);
	//如果是目录,递归删除该目录下的所有文件
	fs.readdirSync(path).forEach((item)=>removeFile(path+"/"+item));
	//最后删除这个空的目录
	fs.rmdirSync(path);
}

6.8 fs.rename() 重命名目录或文件名

  • fs.rename(oldpath,newpath,cb),修改目录或文件名称,是一个异步操作,必须有回调函数。
  • fs.renameSync(oldpath,newpath),修改目录或文件名称,是一个同步操作。
  • 第一个参数oldpath为当前的目录或文件名称,第二个参数newpath为修改后的目录或文件名称,第三个参数cb为回调函数。
  • 如果 newPath 已存在,则会覆盖它。
let fs = require("fs");
// 将aa.txt 重命名为bb.txt
fs.rename('aa.txt', 'bb.txt', (err) => {
  if (err) throw err;
  console.log('重命名完成');
});
//将目录tmp2 重命名为tmp
fs.renameSync("./tmp2","./tmp")

6.9 fs.existsSync() 判断文件夹是否已存在

  • fs.existsSync(path),参数为文件夹路径。
  • 如果路径存在,则返回 true,否则返回 false。
  • fs.exists() 已废弃,使用fs.existsSync() ,即不需要再使用回调。
let fs = require("fs");
if (fs.existsSync('./tmp1/a')) {
  console.log('文件已存在');
}

6.10 fs.stat() 返回文件与目录的信息

  • fs.stat(path,cb),返回文件与目录的信息,是一个异步操作,必须有回调函数。
  • fs.statSync(path),返回文件与目录的信息,是一个同步操作。
  • 第一个参数 path,为文件名称或者目录路径。
  • 回调函数中有两个参数 (err, stats),其中 stats 是一个 fs.Stats 对象。
  • 如果是同步操作,则fs.statSync(path)返回一个 fs.Stats 对象。
  • fs.Stats 对象,有以下方法:
    • stats.isDirectory(),如果path是文件夹,则返回 true。
    • stats.isFile(),如果path是文件,则返回 true。
    • stats.size,返回文件的大小(以字节为单位)。
let fs = require("fs");
const list = ['./txtDir', './txtDir/file.txt'];

for (let i = 0; i < list.length; i++) {
//异步操作
  fs.stat(list[i], function(err, stats) {
    console.log(stats.isDirectory()); //true false
    console.log(stats); //打印结果如下
  });
}
//同步操作
console.log(fs.statSync('./txtDir').isDirectory()); //true

stats 打印结果如下:

Stats {
  dev: 16777220,
  mode: 33188,
  nlink: 1,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 10803859,
  size: 24,
  blocks: 8,
  atimeMs: 1584527766640.159,
  mtimeMs: 1584527742951.745,
  ctimeMs: 1584527742951.745,
  birthtimeMs: 1584526535605.706,
  atime: 2020-03-18T10:36:06.640Z,
  mtime: 2020-03-18T10:35:42.952Z,
  ctime: 2020-03-18T10:35:42.952Z,
  birthtime: 2020-03-18T10:15:35.606Z }

7. crypto 加密

crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码实现这些功能不是不可能,但速度会非常慢。Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。

crypto 模块提供了加密功能,包括对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证功能的一整套封装。

使用MD5、SHA1、Hmac这几种方式,对数据进行加密后,是没有办法解密的。AES的方式,可以对数据进行解密。

7.1 检测是否支持 crypto

可以在不包括支持 crypto 模块的情况下构建 Node.js,这时调用 require(‘crypto’) 将导致抛出异常。

let crypto;
try {
  crypto = require('crypto');
} catch (err) {
  console.log('不支持 crypto');
}

7.2 MD5和SHA1

MD5是一种常用的哈希算法,用于给任意数据一个“签名”。这个签名通常用一个十六进制的字符串表示。

调用 hash.digest() 方法之后, Hash 对象不能被再次使用。 多次调用将会导致抛出错误。

//引入crypto模块
const crypto = require('crypto');
//使用md5模式 创建并返回一个 Hash 对象
const hash = crypto.createHash('md5');
//update 使用给定的内容更新哈希的内容
hash.update('hello world');
//digest 计算传入要被哈希(使用 hash.update() 方法)的所有数据的摘要。
let result = hash.digest('hex');
//打印出结果:5eb63bbbe01eeed093cb22bb8f5acdc3
console.log(result);

7.3 Hmac

Hmac算法也是一种哈希算法,它可以利用MD5或SHA1等哈希算法。不同的是,Hmac还需要一个密钥。

只要密钥发生了变化,那么同样的输入数据也会得到不同的签名,因此,可以把Hmac理解为用随机数“增强”的哈希算法。

调用 hmac.digest() 方法之后, Hmac 对象不能被再次使用。 多次调用 hmac.digest() 将会导致抛出错误

//引入crypto模块
const crypto = require('crypto');
//创建 Hmac 实例
const hmac = crypto.createHmac('sha256', 'secret-key');
//使用给定的内容更新 Hmac 的内容
hmac.update('hello world');
//计算使用 hmac.update() 传入的所有数据的 HMAC 摘要
let result = hmac.digest('hex');
//打印出:095d5a21fe6d0646db223fdf3de6436bb8dfb2fab0b51677ecf6441fcf5f2a67
console.log(result);

7.4 AES

对称加密算法,加密和解密都用相同的秘钥。

const crypto = require('crypto');
//数据加密
function aesEncrypt(data, key) {
	//用指定的算法和秘钥,返回一个cipher对象
	const cipher = crypto.createCipher('aes192', key)
	var crypted = cipher.update(data, 'utf8', 'hex')
	crypted += cipher.final('hex');
	return crypted;
}
//数据解密
function aesDecrypt(encrypted, key) {
	const decipher = crypto.createDecipher('aes192', key)
	var decrypted = decipher.update(encrypted, 'hex', 'utf8');
	decrypted += decipher.final('utf8')
	return decrypted;
}

var data = 'hello world';
var key = 'password';
var encrypted = aesEncrypt(data, key);
var decrypted = aesDecrypt(encrypted, key);
console.log(encrypted); //7e280d9850cd8fc1b99b2ba01f64d609
console.log(decrypted); //hello world

8. stream 流

流(stream)是 Node.js 中处理流式数据的抽象接口。 stream 模块用于构建实现了流接口的对象。所有的流都是 EventEmitter 的实例。

Node.js 中有四种基本的流类型:

  • Writable - 可写入数据的流(例如 fs.createWriteStream())。
  • Readable - 可读取数据的流(例如 fs.createReadStream())。
  • Duplex - 可读又可写的流(例如 net.Socket)。
  • Transform - 在读写过程中可以修改或转换数据的 Duplex 流(例如 zlib.createDeflate())。

流的使用跟gulp中的pipe()类似,都是通过管道将文件进行输出。

const http = require('http');
const server = http.createServer((req, res) => {
  // req 是一个 http.IncomingMessage 实例,它是可读流。
  // res 是一个 http.ServerResponse 实例,它是可写流。

  let body = '';
  // 接收数据为 utf8 字符串,
  // 如果没有设置字符编码,则会接收到 Buffer 对象。
  req.setEncoding('utf8');

  // 如果添加了监听器,则可读流会触发 'data' 事件。
  req.on('data', (chunk) => {
    body += chunk;
  });

  // 'end' 事件表明整个请求体已被接收。 
  req.on('end', () => {
    try {
      const data = JSON.parse(body);
      // 响应信息给用户。
      res.write(typeof data);
      res.end();
    } catch (er) {
      // json 解析失败。
      res.statusCode = 400;
      return res.end(`错误: ${er.message}`);
    }
  });
});

server.listen(1337);

9. zlib 压缩

zlib 模块提供通过 Gzip 和 Deflate/Inflate 实现的压缩功能。

9.1 zlib.createGzip()

压缩或者解压数据流(例如一个文件)通过 zlib 流将源数据流传输到目标流中来完成。

const fs = require('fs');
const zlib = require('zlib');
//创建一个文件
fs.writeFileSync('log.txt', 'gp18');
//读取文件流
fs.createReadStream('log.txt')
	//压缩文件
  .pipe(zlib.createGzip())
  //输出流
  .pipe(fs.createWriteStream('log.txt.gzip'));

更多内置模块,可以查看nodejs官方文档。

你可能感兴趣的:(node.js)