NodeJS——API使用之全局环境

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/TDCQZD/article/details/82179363

一、 __dirname

当前模块的文件夹名称 —解析后的绝对路径。
代码实例:

// 当前模块的文件名称 ---解析后的绝对路径。
console.log(__filename)
// 当前模块的文件夹名称 ---解析后的绝对路径。
console.log(__dirname)

二、__filename

当前模块的文件名称 —解析后的绝对路径。
代码实例:

// 当前模块的文件名称 ---解析后的绝对路径。
console.log(__filename)
// 当前模块的文件夹名称 ---解析后的绝对路径。
console.log(__dirname)

三、 global

在浏览器中,顶层作用域就是全局作用域。
这意味着在浏览器中,var something 会定义一个新的全局变量。 在 Node.js 中则不同,顶层作用域不是全局作用域,var something 的作用域只在模块内,global才是真正的全局作用域对象。

const a = require("./dir/a")
const b =require("./dir/b")

console.log(c,d);
console.log(a.a,b.b);

四、 console

console 模块提供了一个简单的调试控制台,类似于 Web 浏览器提供的 JavaScript 控制台。

五、process

process 对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。 因为是全局变量,所以无需使用 require()。
1、process.argv
process.argv 属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数。第一个元素为process.execPath。第二个元素为当前执行的JavaScript文件路径。剩余的元素为其他命令行参数

node --inspect  01_process.js --damu a=1 b=2

2、 process.execArgv
process.execArgv 属性返回当Node.js进程被启动时,Node.js特定的命令行选项。 这些选项在process.argv属性返回的数组中不会出现,并且这些选项中不会包括Node.js的可执行脚本名称或者任何在脚本名称后面出现的选项

node --inspect  01_process.js --damu a=1 b=2

3、 process.execPath
process.execPath 属性,返回启动Node.js进程的可执行文件所在的绝对路径
4、 process.cwd()
process.cwd() 方法返回 Node.js 进程当前工作的目录
5、 process.nextTick()
process.nextTick()方法将 callback 添加到”next tick 队列”。 一旦当前事件轮询队列的任务全部完成,在next tick队列中的所有callbacks会被依次调用。

代码示例:

    /*
        运行 node --inspect  01_process.js --damu a=1 b=2
    */
    const {argv,execArgv,execPath} = process;
   /* argv.map(function (item) {
        console.log(item)
    })*/
    console.log(execArgv,execPath)
//cwd和node的工作目录有关
console.log(process.cwd())

//其他都针对于文件
console.log(__dirname)
console.log(__filename)
console.log(process.argv[1]);

六、Buffer

1、 理解Buffer
Node的应用场景中存在大量的文件,数据库I/O和网络I/O操作。这使得Node不得不处理大量二进制数据。而在ECMAScript5.1中没有对二进制方面做任何的定义。Javascript自有的字符串远远不能满足这些需求,于是Buffer对象应运而生。
Buffer是一个像Array的对象,但它主要用于操作字节。Buffer是一个典型的Javascript与C++结合的模块。它将性能相关的部分用C++实现。将非性能相关的部分用Javascript实现。Buffer所占用的内存不是通过V8分配的。属于堆外内存。(Buffer对象的内存分配不是在V8的堆内存中,而是在Node的C++层面实现内存的申请的)
由于Buffer对象太过常见,Node在进程启动时就已经加载了它。将其放在了全局对象上。所以在使用Buffer时,无须通过require()即可调用。
2、 Buffer对象
Buffer对象类似于数组,它的元素为16进制的两位数(00-ff ; 0-255)。

var str = "hello word";                     
var buf = new Buffer(str,"utf-8");
console.log(buf);
//<Buffer 68 65 6c 6c 6f 20 e5 b0 9a e7 a1 85 e8 b0 b7>

Node中,文字在UTF-8的编码下占据3个字节。字母 空格占用1个字节。
以上创建buffer的方式以及被废弃。(基于安全性的问题)

1个字节(byte) = 8位(bit)  二进制的00000000  十六进制的00
1byte = 8bit
1kb = 1024byte
1mb = 1024kb
1gb = 1024mb
1tb = 1024gb

3、Buffer创建

// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);
// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);
const buf5 = Buffer.from('tést');

4、Buffer内存分配
Buffer对象的内存分配不是在V8的堆内存中,而是在Node的C++层面实现内存的申请的。因为要处理大量的字节数据。所以不能采用要一点内存就向操作系统申请一点内存的方式。这可能造成大量内存申请的系统调用。对操作系统有一定的压力。为此Node的解决方案是:C++层面申请内存,javascript分配C++申请的内存。
Node以8k(Buffer.poolSize)为界限来区分Buffer是大对象还是小对象。

1)分配小Buffer对象

为了高效的使用申请来的内存,Node在小对象Buffer上采用了slab分配机制。
slab是一种动态内存管理机制。最早诞生于SunOS操作系统。目前在Linux操作系统中也有广泛的应用。
简单而言,slab就是一块申请好的固定大小的内存区域。它具有三个状态

  • Full :完全分配
  • Partial :部分分配
  • Empty :未分配

处于Empty状态的slab
这里写图片描述
new Buffer(1024)
这里写图片描述
new Buffer(4000)
这里写图片描述
如果slab的剩余空间不够用,将会构造新的slab,原slab中剩余的空间会造成浪费。比如第一次构造1个字节的Buffer对象。第二次构造8192字节的Buffer对象。由于第二次分配时,slab不够用了。这时系统会创建并使用一个新的slab。第一个slab会被浪费8191个字节。容易产生内存泄漏。

2)分配大Buffer对象
如果需要分配超过8k的Buffer,javascript层就会通知C++层直接申请一个size大于8k的slab。整个slab都会给这个Buffer用

5、基本的Buffer API

//返回一个buffer的字节容量
const buf = Buffer.alloc(10);
console.log(buf.length);

//可以通过下标的方式访问Buffer元素
/*如果元素的赋值小于0,就将该值逐次加256,直到得到一个0到255之间的整数。如果元素的赋值大于255,就逐次减256,直到得到0到255之间的整数。如果元素的赋值是小数。舍弃小数的部分,只保留整数部分。*/
buf[0] = 100;

//Buffer的静态方法
Buffer.byteLength(str) :返回字符串包含的字节数
Buffer.isBuffer(obj)    :检测对象是否是一个Buffer对象
Buffer.concat() :返回一个合并了给定数组中所Buffer实例的新Buffer

//Buffer的实例方法
buf.length:返回buf分配到的字节数。  length 属性不是不可变的。
buf.toString():将buf转为字符串 默认编码utf8
buf.fill(val,start,end):在buf的[start,end)区域平铺val
buf.write(val,start):从buf的start位开始填充val
buf.equals(otherBuffer):
    如果 buf 与 otherBuffer 具有完全相同的字节,则返回 true,否则返回 false。
buf.indexOf(val):
     buf中value 最后一次出现的索引,如果buf没包含 value 则返回 -1
buf.copy(target,targetStart,sourceStart,sourceEnd):
       target 要拷贝进的 Buffer
       targetStart  target 中开始拷贝进的偏移量。 默认: 0
       sourceStart  buf 中开始拷贝的偏移量。 默认: 0
       sourceEnd    buf 中结束拷贝的偏移量(不包含)。 默认: buf.length

6、如何解决中文乱码?
引入string_decoder模块解决中文乱码的问题

const { StringDecoder } = require('string_decoder');
const decoder = new StringDecoder('utf8');
//使用string_decoder解决中文乱码的问题
for(let i=0;i<buf.length;i+=5){
    const b = Buffer.allocUnsafe(5);
    buf.copy(b,0,i);
    console.log(decoder.write(b));
}

7、代码案例:

01_buffe创建.js

const  buffer =new Buffer("欢迎学习Node","utf-8")//不推荐此创建方式,不安全
console.log(buffer.length)
console.log(buffer)

const  buffer2 = Buffer.alloc(10)//推荐使用
console.log(buffer2.length)
console.log(buffer2)

const  buffer3 = Buffer.allocUnsafe(10)//不安全
console.log(buffer3.length)
console.log(buffer3)

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);
console.log(buf4.length)
console.log(buf4)
const buf5 = Buffer.from('tést');
console.log(buf5.length)
console.log(buf5)

02_bufferAPI.js

//返回一个buffer的字节容量
const buf = Buffer.alloc(10);
console.log(buf.length);

//可以通过下标的方式访问Buffer元素
/*如果元素的赋值小于0,就将该值逐次加256,直到得到一个0255之间的整数。
如果元素的赋值大于255,就逐次减256,直到得到0255之间的整数。
如果元素的赋值是小数。舍弃小数的部分,只保留整数部分。*/

buf[0] = 100;

/*
Buffer的静态方法

Buffer.byteLength(str) //返回字符串包含的字节数

Buffer.isBuffer(obj)    //检测对象是否是一个Buffer对象

Buffer.concat() //返回一个合并了给定数组中所Buffer实例的新Buffer
*/

/*
Buffer的实例方法

buf.length //返回buf分配到的字节数。  length 属性不是不可变的。

buf.toString()//将buf转为字符串 默认编码utf8

buf.fill(val,start,end)//在buf的[start,end)区域平铺val

buf.write(val,start)//buf的start位填充val

buf.equals(otherBuffer)//如果 buf 与 otherBuffer 具有完全相同的字节,则返回 true,否则返回 false。

buf.indexOf(val)//buf中value 最后一次出现的索引,如果buf没包含 value 则返回 -1

buf.copy(target,targetStart,sourceStart,sourceEnd)
target 要拷贝进的 Buffer
targetStart  target 中开始拷贝进的偏移量。 默认: 0
sourceStart  buf 中开始拷贝的偏移量。 默认: 0
sourceEnd    buf 中结束拷贝的偏移量(不包含)。 默认: buf.length

 */

03_buffer中文乱码.js

const { StringDecoder } = require('string_decoder');
const decoder = new StringDecoder('utf8');

var buf = Buffer.from('你好,时间!');
// for(let i=0;i<buf.length;i+=5){
//     const b = Buffer.allocUnsafe(5);
//     //  buf.copy(b,0,10);
//     buf.copy(b,0,i);
//     console.log(b.toString());
// }

//使用string_decoder解决中文乱码的问题
for(let i=0;i<buf.length;i+=5){
    const b = Buffer.allocUnsafe(5);
    buf.copy(b,0,i);
    console.log(decoder.write(b));
}

猜你喜欢

转载自blog.csdn.net/TDCQZD/article/details/82179363