Node.js 全局对象Buffer对象流
Posted YuLong~W
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js 全局对象Buffer对象流相关的知识,希望对你有一定的参考价值。
全局对象
全局属性
- __filename 指向当前正在执行的脚本文件名
- __dirname 指向当前运行的脚本所在的目录(路径)
全局对象
1、global对象:
表示 Node 所在的全局环境,类似于浏览器中的window对象。所有全局变量都是global对象的属性,如:console、process等。
在浏览器中全局对象是window,在Node中全局对象是global
Node中全局对象下有以下方法,可以在任何地方使用,global可以省略
方法 | 说明 |
---|---|
console.log() | 在控制台中输出 |
setTimeout() | 设置超时定时器 |
clearTimeout() | 清除超时时定时器 |
setInterval() | 设置间歇定时器 |
clearInterval() | 清除间歇定时器 |
2、console对象:
指向Node内置的console模块,提供命令行环境中的标准输入、标准输出功能。通常是写console.log()。
全局console实例对象:
console.log('hello world'); // 打印hello world到标准输出流
console.log('hello %s', 'world');// 打印hello world到标准输出流
console.error(new Error('错误信息')); //打印 [Error: 错误信息] 到标准错误流
const name = 'Robert';
console.warn(`Danger ${name}! Danger!`);// 打印Danger Robert! Danger!到标准错误流
Console类:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world'); // 打印hello world到out流
myConsole.log('hello %s', 'world'); //打印hello world到out流
myConsole.error(new Error('错误信息')); //打印 [Error: 错误信息] 到 err流
const name = 'Robert';
myConsole.warn(`Danger ${name}! Danger!`); //打印Danger Robert! Danger!到 err流
3、process:进程对象
process对象是 Node 的一个全局对象,提供当前 Node 进程的信息。它可以在脚本的任意位置使用,不必通过require命令加载。该对象部署了EventEmitter接口
process对象属性:
属性 | 描述 |
---|---|
process.argv | 返回一个数组,成员是当前进程的所有命令行参数。 |
process.env | 返回一个对象,成员为当前Shell的环境变量。 |
process.installPrefix | 返回一个字符串,表示 Node 安装路径的前缀。 |
process.pid | 返回一个数字,表示当前进程的进程号。 |
process.platform | 返回一个字符串,表示当前的操作系统,比如Linux。 |
process.title | 返回一个字符串,默认值为node,可以自定义该值。 |
process.version | 返回一个字符串,表示当前使用的 Node 版本。 |
process.stdout:属性返回一个对象,表示标准输出。该对象的write方法等同于console.log,可用在标准输出向用户显示内容
process.stdout.write('Hello World');
process.stdin:返回一个对象,表示标准输入,利用该对象可以从标准输入终端向node程序输入数据
process.stdout.write('请输入数据:')
process.stdin.on('data',(data)=>{
process.stdout.write("输入的数据是:"+data.toString().trim())
process.exit(0) //结束进程
})
stderr:指向标准错误
process对象方法:
方法 | 描述 |
---|---|
process.on() | 监听事件 |
process.exit() | 退出当前进程 |
process.chdir() | 切换工作目录到指定目录 |
process.cwd() | 返回运行当前脚本的工作目录的路径 |
process.getgid() | 返回当前进程的组ID(数值) |
process.getuid() | 返回当前进程的用户ID(数值) |
process.nextTick() | 指定回调函数在当前执行栈的尾部、下一次Event Loop之前执行 |
process.setgid() | 指定当前进程的组,可以使用数字ID,也可以使用字符串ID |
process.setuid() | 指定当前进程的用户,可以使用数字ID,也可以使用字符串ID |
process.on():
process对象部署了EventEmitter接口,可以使用on方法监听各种事件,并指定回调函数
process支持的事件还有下面这些:
- data事件:数据输出输入时触发
- SIGINT事件:接收到系统信号SIGINT时触发,主要是用户按Ctrl + c时触发。
- SIGTERM事件:系统发出进程终止信号SIGTERM时触发
- exit事件:进程退出前触发
例如:进程退出时,显示一段日志
process.on("exit", code =>
console.log("exiting with code: " + code))
注意: 此时回调函数只能执行同步操作,不能包含异步操作,因为执行完回调函数,进程就会退出,无法监听到回调函数的操作结果。
Buffer对象
- Buffer对象是专门用于处理二进制数据的对象(接口),由Node原生创建,可以直接使用不需要导入
- Buffer对象又称为缓冲区对象,它有一个构造函数,由构造函数创建的对象,v8引擎会为其分配一块内存
- Buffer中存放的数据是0~255之间的整数值(即一个字节的数据)
Buffer实例对象用法
1、创建Buffer实例对象:
- (1)使用new运算符
var 变量 = new Buffer([参数])
- (2)使用from函数
var 变量 = Buffer.from([参数])
- (3)使用alloc函数
var 变量 = Buffer.alloc(size,fill)
2、Buffer用于编码转换:
-
Buffer实例一般用于表示编码字符的序列,如UTF-8、UCS2、Base64或十六进制编码的数据。
-
在文件操作和网络操作中,如果没有显式声明编码格式,返回数据的默认类型为Buffer。
-
通过使用显式字符编码将Buffer实例与javascript字符串相互转换。
-
在创建Buffer实例时指定存入字符串的字符编码
const buf = Buffer.from('hello world', 'ascii');
-
将Buffer实例转换成字符串的语法:
buf.toString([encoding[, start[, end]]])
const buf = Buffer.from('tést'); console.log(buf.toString('hex'));// 输出结果: 74c3a97374 console.log(buf.toString('utf8', 0, 3));//输出结果:té
3、Buffer转换为JSON对象:
JSON(JavaScript Object Notation)对象:是前后端数据交换的常用格式,是以 key-value 的方式保存数据,由于体积小、创建方便、解析简单,所以被广泛使用。只要应用程序需要将结构化信息作为文本进行交换或存储,即可使用它
-
使用
buf.toJSON()
方法将Buffer实例转换为JSON对象,适用于将二进制数据转换为JSON格式const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); const json = JSON.stringify(buf); console.log(json); // 输出:{"type":"Buffer","data":[1,2,3,4,5]}
4、Buffer实例基本操作:
-
(1) 写入Buffer实例:使用 buf.write() 方法将字符串写入Buffer实例
语法:buf.write(string[, offset[, length]][, encoding])
const buf = Buffer.alloc(256); let len = buf.write('\\u00bd+\\u00bc=\\u00be',0); console.log(`${len}个字节:${buf8.toString('utf8',0,len)}`); // 输出: 12 个字节: ½ + ¼ = ¾
-
(2) 从Buffer实例读取数据:使用 buf.toString() 方法从Buffer实例读取字符串,也可以使用其他专用方法如 buf.readInt8() 从Buffer实例读取其他类型的数据
const buf = Buffer.from([-1, 5]); console.log(buf.readInt8(0));// 输出结果: -1 console.log(buf.readInt8(1));// 输出结果: 5 console.log(buf.readInt8(2));// 抛出异常 ERR_OUT_OF_RANGE(超出范围)
-
(3) Buffer实例合并:使用 Buffer.concat() 方法
语法:Buffer.concat(list[, totalLength])
-
(4) Buffer实例复制:使用 buf.copy() 方法
语法:buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])
-
(5) Buffer实例切片:使用 buf.slice() 方法
语法:buf.slice([start[, end]])
流
-
流可以看作是某段时间内从一个点移动到另一个点的数据序列
-
Node.js中的流用于管理和处理数据,使用流完成对大量数据的操作以及逐段处理的操作
-
流是Node.js中处理流式数据的抽象接口
-
stream模块用于构建实现了流接口的对象 。主要用于开发人员创建新类型的流实例
const stream = require('stream');
流的基本类型:
- 可写流(Writable)
- 可读流(Readable)
- 双工流(Duplex)
- 转换流(Transform)
流的实现类型:
- 普通的流:基于字符串和Buffer(或Uint8Array)工作
- 对象模式的流:使用其他类型的JavaScript值工作
可写流和可读流 都会在内部的缓冲器中存储数据,可缓冲的数据大小取决于传入流构造函数的highWaterMark选项(相当于水位线)。
双工流和转换流 都是可读又可写的,各自维护着两个相互独立的内部缓冲器用于读取和写入。在维护数据流时,读取和写入两端可以各自独立地工作。
可读流
- 可读流是对提供数据的来源的一种抽象。所有可读流都实现了stream.Readable类定义的接口
- 可读流有两种模式:流动(Flowing)和暂停(Paused)
-
stream.Readable类定义的主要事件 :
- data:当有数据可读时被触发
- end:没有更多的数据可读时被触发
- close:当流或其底层资源被关闭时被触发
-
stream.Readable类定义的主要方法:
- readable.read([size]):从内部缓冲区拉取并返回数据
- readable.pause():使流动模式的流停止触发data事件,并切换出流动模式
- readable.setEncoding(encoding):为从可读流读取的数据设置字符编码
操作示例:
const fs = require('fs')
//以流的方式读取文件
var readStream=fs.createReadStream('d:/demo.txt');
var str='';//保存数据
readStream.on('data',function(chunk){
str+=chunk;
})
//读取完成
readStream.on('end',function(chunk){
console.log(str);
})
//读取失败
readStream.on('error',function(err){
console.log(err);
})
可写流
- 可写流是对数据被写入的目的地的一种抽象
- 所有可写流都实现了 stream.Writable类 定义的接口
- stream.Writable类定义的主要事件 :
- close:当流或其底层资源被关闭时被触发
- error:写入数据发生错误时被触发
- finish:调用stream.end()方法且缓冲数据都已传给底层系统之后被触发
- stream.Writable类定义的主要方法:
- writable.write(chunk[, encoding][,callback]):写入数据到流,并在数据被完全处理之后调用回调函数。
操作示例:
const fs = require('fs')
var str = '这首歌真的很好听呢';
// 创建一个可以写入的流,写入到文件output.txt 中
var writerStream = fs.createWriteStream('d:/output.txt');
// 使用 utf8 编码写入数据
writerStream.write(str,'UTF8');
// 标记文件末尾
writerStream.end();
// 处理流事件
writerStream.on('finish', function() {
console.log('写入完成!');
});
writerStream.on('error', function(err){
console.log('写入失败');
});
管道读写操作
- 管道操作将从一个流中获取的数据传递到另外一个流中
- 可读流提供的 readable.pipe() 方法在可读流与可写流之间架起桥梁
- 语法:
readable.pipe(destination[, options])
- 将可读流的所有数据通过管道推送到文件的示例 :
const readable = getReadableStreamSomehow();//创建一个可读流 const writable = fs.createWriteStream('d:/file.txt'); // 创建一个可写流 readable.pipe(writable); //管道读写操作,将readable 的所有数据都推送到文件file.txt
- 在单个可读流上绑定多个可写流,对流进行 链式管道操作(zip) 的示例:
const fs = require('fs'); const r = fs.createReadStream('d:/file.txt'); const z = zlib.createGzip(); const w = fs.createWriteStream('d:file.txt.gz'); r.pipe(z).pipe(w);// 链式管道操作两个可写流
- 默认当来源可读流触发end事件时,目标可写流也会调用 stream.end() 结束写入
- 禁用默认行为,end选项设为false,目标流就会保持打开状态
reader.pipe(writer, { end: false }); reader.on('end', () => { writer.end('结束'); });
- 可读流发生错误,目标可写流不会自动关闭,需要手动关闭所有流以避免内存泄漏
- readable.unpipe() 方法用于解绑之前使用stream.pipe()方法绑定的可写流
以上是关于Node.js 全局对象Buffer对象流的主要内容,如果未能解决你的问题,请参考以下文章