Node中经常使用的一些模块

1. process

process是一个全局的变量,因此使用的时候是不须要执行require操做,能够直接使用。css

这里分两部分来讲明,第一个就是能够借助它去获取进程信息,好比进程工做的时候本地是一个什么样的环境,经过process能够获取。第二个经过process能够对当前的进程作一些操做,好比说能够监听进程执行过程当中内置的事件,建立子进程完成更多的操做。html

1. 内存相关获取

// 查看内存消耗
console.log(process.memoryUsage());
/** * rss: 常驻内存 * heapToal: 总内存大小 * heapUsed: 已使用内存 * external: 扩展内存 - 底层模块占用的C/C++核心模块 * arrayBuffers: 缓冲区大小 */
复制代码

2. CPU相关信息获取

console.log(process.cpuUsage());
/** * user: 用户占用的时间片断 * system: 系统占用的时间片断 */
复制代码

3. 运行时能够经过process查看运行目录,Node环境,cpu架构,用户环境,系统平台。

process.cwd(); // 运行目录
process.version; // Node版本
process.versions; // 运行环境版本
process.arch; // cpu架构
process.env.Node_ENV; // 环境 须要先设置
process.env.PATH; // 环境变量
process.env.USERPROFILE; // 管理员目录路径 不一样环境方式不同 process.env.HOME
process.platform; // 平台 win32 macos

复制代码

4. 运行时能够获取启动参数,PID,运行时间,

process.argv; // 获取运行参数,空格分隔可在数组中获取到,默认会存在Node目录和执行脚本的目录两个值。
process.argv0; // 获取第一个值, 只有这一个api
process.pid; // 获取运行的pid
process.ppid; 
process.uptime; // 脚本运行时间
复制代码

事件监听在process中提供的内容。这里不会着重说明process里面到底有哪些事件,主要仍是看一看在NodeJS里面熟悉一下事件驱动编程以及发布订阅的模式。前端

process是实现了emit接口的。可使用on监听事件,内部提供了不少的事件,好比exit,程序退出的时候执行。这里绑定的事件只能执行同步代码,是不能够执行异步代码的,这里要注意。linux

process.on('exit', (code) => { // 退出时
    console.log(code); // 0
})

process.on('beforeExit', (code) => { // 退出以前
    console.log(code); // 0
})
复制代码

手动退出,这种退出不会执行beforeExit,并且exit后面的代码也不会执行,由于执行exit就已经退出了。算法

process.exit();
复制代码

5. 标准输出,输入,错误

process.stdout; // 是一个流,能够对他进行读写操做。

process.stdout.write('123'); // 123
复制代码
const fs = require('fs');

fs.createReadStream('text.txt').pipi(process.stdout); // 读取文件输出。
复制代码
process.stdin; // 能够拿到控制台输入的内容
process.stdin.pipe(process.stdout); // 输入以后输出
复制代码
// 设置字符编码
process.stdin.setEncoding('utf-8');
// 监听readable事件,是否可读也就是有无内容
process.stdin.on('readable', () => {
    // 获取输入的内容
    let chunk = process.stdin.read();
    if (chunk !== null) {
        process.stdout.write(chunk);
    }
})
复制代码

2. path

Node中的内置模块,能够直接使用require将它导入,他的主要做用就是处理文件的目录和路径。只须要调用不一样的方法。path至关于一个工具箱,只须要掌握它里面提供的工具,也就是方法。macos

const path = require('path');
复制代码

1. basename()

获取路径中基础名称编程

path.basename(__filename); // test.js
// 传入第二个参数若是匹配会省略后缀,不匹配仍旧返回真实的后缀
path.basename(__filename, '.js'); // test
path.basename('/a/b/c'); // c
path.basename('/a/b/c/'); // c
复制代码

2. dirname()

获取路径中的目录名称api

path.dirname(__filename); // d:\Desktop\test
path.dirname('/a/b/c'); // /a/b
path.dirname('/a/b/c/'); // /a/b
复制代码

3. extname()

获取路径中的扩展名称数组

path.extname(__filename); // .js
path.extname('/a/b'); //
path.extname('/a/b/index.html.js.css'); // .css
path.extname('/a/b/index.html.js.'); // .
复制代码

4. isAbsolute()

获取路径是不是绝对路径浏览器

path.isAbsolute('a'); // false
path.isAbsolute('/a'); // true
复制代码

5. join()

拼接多个路径片断,还原成完整可用路径

path.join('a/b', 'c', 'index.html'); // a/b/c/index.html
path.join('/a/b', 'c', 'index.html'); // /a/b/c/index.html
path.join('a/b', 'c', '../', 'index.html'); // a/b/index.html
复制代码

6. resove()

返回一个绝对路径

path.resove(); // 获取绝对路径
复制代码

7. parse()

解析路径

const obj = path.parse('/a/b/c/index.html');
/** * root: / * dir: /a/b/c * base: index.html * ext: .html * name: index */
复制代码

8. format()

序列化路径,与parse功能相反, 将对象拼接成完整的路径。

path.format({
    root: '/',
    dir: '/a/b/c',
    base: 'index.html',
    ext: '.html',
    name: 'index'
});
// /a/b/c/index.html
复制代码

9. normalize()

规范化路径,将不可用路径变为可用路径, 这个方法注意若是有转译字符会转译。

path.normalize('a/b/c/d'); // a/b/c/d
path.normalize('a//b/c../d'); // a/b/c../d
path.normalize('a\\/b/c\\/d'); // a/b/c/d 
复制代码

3. Buffer

Buffer通常称为缓冲区,能够认为由于Buffer的存在让开发者可使用js操做二进制IO行为操做的就是二进制数据。NodeJS中的Buffer是一片内存空间。他的大小是不占据V8内存大小的,Buffer的内存申请不是由Node生成的。只是回收的时候是V8GC进行回收的。

BufferNodeJS中的一个全局变量,无需require就能够直接使用。通常配合stream流使用,充当数据的缓冲区。

alloc能够建立指定字节大小的Buffer,默认没有数据

allocUnsafe 建立指定大小的Buffer可是不安全,使用碎片的空间建立Buffer,可能存在垃圾脏数据,不必定是空的。

from 接收数据建立Buffer

v6版本以前是能够经过实例化建立Buffer对象的,可是这样建立的权限太大了,为了控制权限,就限制了实例化建立的方式。

// 建立Buffer
const b1 = Buffer.alloc(10);
const b2 = Buffer.allocUnsafe(10);
复制代码

from建立Buffer能够接收三种类型,字符串,数组,Buffer。 第二个参数是编码类型。

const b3 = Buffer.from('1');
const b4 = Buffer.from([1, 2, 3]);
复制代码

Buffer的一些常见实例方法。

fill: 使用数据填充Buffer,会重复写入到最后一位

write:向Buffer中写入数据,有多少写多少,不会重复写入。

toString: 从Buffer中提取数据

slice: 截取Buffer

indexOf:在Buffer中查找数据

copy: 拷贝Buffer中的数据

Buffer的静态方法。

concat: 将多个Buffer拼接成一个新的Buffer

isBuffer: 判断当前数据是不是一个Buffer

Buffersplit方法实现。

Array.Buffer.splice = function(sep) {
    let len = Buffer.form(sep).length;
    let ret = [];
    let start = 0;
    let offset = 0;

    while(offset = this.indexOf(sep, start) !== -1) {
        ret.push(this.slice(start, offset))
        start = offset + len;
    }
    ret .push(this.slice(start));
    return ret;
}
复制代码

4. fs

NodeBufferStream随处可见,他们用于操做二进制数据。

fs是一个内置的核心模块,全部与文件相关的操做都是经过fs来进行实现的,好比文件以及目录的建立,删除,信息的查询或者文件的读取和写入。

若是想要操做文件系统中的二进制数据须要使用fs模块提供的API,这个过程当中BufferStream又是密不可分的。

介绍fs模块以前咱们首先须要介绍一下文件系统的基础知识,好比权限位,标识符,文件描述符等。

权限是指当前的操做系统内不一样的用户角色对于当前的文件能够执行的不一样权限操做,文件的权限操做被分为r,w,x三种, r是读权限,w是写权限,x是执行权限。若是用8进制的数字进行表示r4w2x1,若是不具有该权限就是一个0

操做系统中将用户分为三类分别是文件的全部者,通常指的是当前用户本身,再有就是文件的所属组,相似当前用户的家人,最后是其余用户也就是访客用户。

Nodeflag表示对文件操做方式,好比是否可读可写。

r: 表示可读

w: 表示可写

s: 表示同步

+: 表示执行相反操做

x: 表示排他操做

a: 表示追加操做

fd就是操做系统分配给被打开文件的标识,经过这个标识符文件操做就能够识别和被追踪到特定的文件。不一样操做系统之间是有差别的,Node为咱们抹平了这种差别。

Node每操做一个文件,文件描述符就会递增一次,而且它是从3开始的。由于013已经被输入,输出和错误占用了。后面咱们在使用fs.open打开文件的时候就会获得这个fd

fs任何文件操做api都有同步和异步两种方式,这里只演示异步API,同步基本也相同

1. 文件读写

readFile: 从指定文件中读取数据

const fs = require('fs');
const path = require('path');

fs.readFile(path.resolve('aaa.txt'), 'utf-8', (err, data) => {
    console.log(err);
    console.log(data);
})

复制代码

writeFile: 向指定文件中写入数据

fs.writeFile('bbb.txt', 'hello', {
    mode: 438, // 操做位
    flag: 'w+',
    encoding: 'utf-8'
}, (err) => {
    console.log(err);
})
复制代码

appendFile: 追加的方式向指定文件中写入数据

fs.appendFile('bbb.txt', 'hello', {}, (err) => {
    console.log(err);
})
复制代码

copyFile: 将每一个文件中的数据拷贝到另外一个文件

fs.copyFile('aaa.txt', 'bbb.txt', (err) => {
    console.log(err);
})
复制代码

watchFile: 对指定文件进行监控

fs.watchFile('bbb.txt', {
    interval: 20 // 20ms监控一次
}, (curr, prev) => {
    console.log(curr); // 当前信息
    console.log(prev); // 前一次信息
    if (curr.mtime !== prev.mtime) {
        // 文件被修改了
    }
})

fs.unwatchFile('bbb.txt'); // 取消监控
复制代码

2. 文件打开与关闭

前面咱们使用了fs实现了文件的读写操做,既然已经读写了就证实已经实现了文件的打开,为何Node还要单独的提供打开关闭的api呢?

由于readFilewriteFile的工做机制是将文件里的内容一次性的所有读取或者写入到内存里,而这种方式对于大致积的文件来说显然是不合理的,所以须要一种能够实现边读编写或者边写边读的操做方式,这时就须要文件的打开、读取、写入、关闭看作是各自独立的环节,因此也就有了openclose

const fs = require('fs');
const path = require('path');

// open
fs.open(path.resolve('aaa.txt'), 'r', (err, fd) => {
    console.log(err);
    console.log(fd);

    fs.close(fd, (err) => {

    });
})
复制代码

3. 目录操做

access: 判断文件或目录是否具备操做权限

fs.access('aaa.txt', (err) => {
    console.log(err); // 存在错误就是没有权限
})
复制代码

stat: 获取目录及文件信息

fs.stat('aaa.txt', (err, stat) => {
    console.log(stat); // size isFile(), isDirectory()
})
复制代码

mkdir: 建立目录

fs.mkdir('a/b/c', {
    recursive: true, // 递归建立
}, (err) => {
    console.log(err);
})
复制代码

rmdir: 删除目录

fs.rmdir('a', {
    recursive: true, // 递归删除
}, (err) => {
    console.log(err);
})
复制代码

readdir: 读取目录中内容, 不会递归子目录

fs.readdir('a', (err, files) => {
    console.log(files);
})
复制代码

unlink: 删除指定文件

fs.unlink('a', (err) => {
    console.log(err);
})
复制代码

6. commonjs

CommonJS的出现是为了解决前端模块化,他的做者但愿能够倒逼浏览器们实现前端模块化,可是因为浏览器自己具有的单线程阻塞的特色,CommonJS并不能适用于浏览器平台。CommonJS是一个超集,他是语言层面的规范,模块化只是这个规范中的一个部分。

7. Events

Node中经过EventEmitter类实现事件统一管理。实际开发中基本不多引入这个类。这个类大部分供内置模块使用的, 好比fshttp都内置了这个模块。

Node是基于事件驱动的异步操做架构,内置events模块,模块提供了EventEmitter类,他的实例对象具有注册事件和发布事件删除事件的常规操做。

on:添加当事件被触发时调用的回调函数

emit: 触发事件,按照注册的顺序调用每一个事件监听器

once: 注册执行一次的监听器

off:移除特定的监听器

const EventEmitter = require('events');

const ev = new EventEmitter();

ev.on('event', () => {

})

ev.emit('event');
复制代码

7. stream

并非NodeJS首创的内容,在linux系统中可使用ls | grep *.js命令操做,其实就是将ls命令获取到的内容交给grep去处理,这就是一个流操做。

使用流能够从空间和时间上提高效率,NodeJS诞生之初就是为了提升IO性能,其中最经常使用的文件系统和网络他们就是流操做的应用者。

NodeJS中流就是处理流式数据的抽象接口,NodeJS中的stream对象提供了用于操做流的对象。对于流来讲只有多使用才能加深了解。

流的分段处理能够同时操做多个数据chunk,同一时间流无须占据大内存空间。流配合管道,扩展程序会变得很简单。

NodeJS中内置了stream模块,它实现了流操做对象。Stream模块实现了四个具体的抽象。全部的流都继承自EventEmitter

Readable: 可读流,可以实现数据的获取。

Writeable: 可写流,可以实现数据的写操做。

Duplex: 双工流,便可度又可写。

Tranform: 转换流,可读可写,还能实现数据转换。

const fs = require('fs');

const rs = fs.createReadStream('./a.txt');
const ws = fs.createWriteStream('./b.txt');

rs.pipe(ws);
复制代码

1. 可读流

生产供消费的数据流。

const rs = fs.createReadStream('./a.txt');
复制代码
const { Readable } = require('stream');

const source = ['a', 'b', 'c'];

class MyReadable extends Readable {
    constructor() {
        super();
        this.source = source;
    }
    _read() {
        const data = this.source.shift() || null;
        this.push(data);
    }
}

const myreadable = new MyReadable(source);

myreadable.on('data', (chunk) => {
    console.log(chunk.toString());
})
复制代码

2. 可写流

用于消费数据的流,响应。

const ws = fs.createWriteStream('./b.txt');
复制代码
const { Writable } = require('stream');

class MyWriteable extends Writable {
    constructor() {
        super();
    }
    _write (chunk, en, done) {
        process.stdout.write(chunk.toString());
        process.nextTick(done);
    }
}

const mywriteable = new MyWriteable();

mywriteable.write('yindong', 'utf-8', () => {
    consoel.log('end');
})
复制代码

3. Duplex

const { Duplex } = require('stream');

class MyDuplex extends Duplex {
    constructor(source) {
        super();
        this.source = source;
    }
    _read() {
        const data = this.source.shift() || null;
        this.push(data);
    }
    _write(chunk, en, next) {
        process.stdout.write(chunk);
        process.nextTick(next);
    }
}

const source = ['a', 'b', 'c'];

const myDuplex = new MyDuplex(source);

mtDuplex.on('data', (chunk) => {
    console.log(chunk.toString());
})

mtDuplex.write('yindong', () => {
    console.log('end');
})

复制代码

4. Transform

const { Transform } = require('stream');

class MyTransform extends Transform {
    constructor() {
        super();
    }
    _transform(chunk, en, cb) {
        this.push(chunk.toString().toUpperCase());
        cb(null);
    }
}

const t = new MyTransform();

t.write('a');

t.on('data', (chunk) => {
    console.log(chunk.toString());
})
复制代码

8. 链表

链表是一种数据存储结构。

在文件可写流的write方法工做的时候,有些被写入的内容须要在缓冲区排队等待的,并且遵循的是先进先出的规则,为了保存这些排队的数据,在新版的Node中就采用了链表的结构来存储这些数据。

相比较数组来讲,链表的优点更明显,在多个语言下,数组存放数据的长度是有上限的,数组在执行插入或者删除操做的时候会移动其余元素的位置,而且在JS中数组被实现成了一个对象。因此在使用效率上会低一些。

固然这都是相对的,实际应用中数组的做用仍是很强大的。

链表是由一系列节点组成的集合。这里的节点都称为Node节点,每一个节点的身上都有一个对象的引用是指向下一个节点,将这些指向下一个节点的引用组合到一块儿也就造成了一个链,对于链表结构来讲咱们常听到的会有不一样类型,双向链表,单向链表,循环链表。经常使用的通常是双向链表。

9. Assertion

断言, 若是不符合,会中止程序,并打印错误

const assert = require('assert');
// assert(条件, 一段话)
function sum(a, b) {
  assert(arguments.length === 2,  '必须有两个参数');
  assert(typeof a === 'number',  ‘第一个参数必须是数字’);
}
复制代码

10. C++ Addons

使用c语言写的插件,在Node中使用。

11. Cluster

多线程

一个程序就是一个进程,一个进程会有多个线程 进程和进程是严格隔离的,拥有独立的执行空间。 同一个进程内的全部线程共享一套空间、代码

  1. 多进程

成本高,速度慢,安全,进程间通讯麻烦,写代码简单。

  1. 多线程

成本低,速度快,不安全,线程间通讯简单,写代码复杂。

Child_Processes, Cluster, Process

12. Command Line Options

获取命令行参数

13. Crypto

签名,完成加密算法的

const cryptp = require("crypto");
let obj = cryto.createHash('md5');
obj.update('123');
console.log(obj.digest('hex')); // MD5 32位
复制代码

14. OS

系统相关

const os = require('os');
// 获取cpu个数
os.cpus(); 
复制代码

15. Events

事件队列

const Event = require('events').EventEmitter;
let ev = new Event();
// 绑定事件
ev.on('msg', function(a, b,c) {
    console.log(a, b, c); // 12 , 3, 8
})
// 派发事件
ev.emit('msg', 12,3,8);
复制代码

本身实现一个Events:

class EventEmitter {
    constructor() {
        this._events = {};
    }
    on(eventName, callBack) {
        if (this._events[eventName]) {
            this._events[eventName].push(callBack);
        } else {
            this._events[eventName] = [callBack];
        }
        
    }
    emit(eventName) {
        this._events[eventName].forEach(fn => {
            fn();
        })
    },
    off(eventName, callBack) {
        this._events[eventName] = this._events[eventName].filter(fn => fn !== callBack)
    }
}

复制代码

16. url

请求url模块

const url = require('url');
url.parse('url', true); // 会解析出url和参数,包含query-string的功能。
复制代码

17. Net

TCP 稳定 Net

UDPUDP/Datagram

DNS/Domain

18. DNS

域名解析成ip

const dns = require('dns');
dns.resolve('baidu.com', (err, res) => {
})
复制代码

19. http

基于nethttp服务

const http = require('http');
const server = http.createServer((request, response) => {
    // request 为请求数据
    // response 为响应数据
    // 设置返回值类型
    res.writeHead(200, {'Content-type' : 'text/html'});
    response.write = 'server start';
    return response.end(); // 结束
});
server.listen(3000); // 服务监听的端口号
复制代码
相关文章
相关标签/搜索