初学node,你必须懂的几个api

初学node,你必须懂的几个api_第1张图片
图片发自App

这两天在工作之余学习Node.js,整理了其中一些基础api,并写了一些基础的demo

下面是自己对于pathbuffereventfs这几个常用到api的一些用法整理。

一,PATH

模块提供了一些工具函数,用于处理文件与目录的路径。

1,path.normalize(path)

path.normalize() 方法会规范化给定的 path,并解析 '..''.' 片段

例子

const { normalize } = require('path');

console.log(normalize('/user//local/bin'));
console.log(normalize('/user//local/../bin'));

结果如图

path1.png

2,path.join([...paths])

path.join() 方法使用平台特定的分隔符把全部给定的 path 片段连接到一起,并规范化生成的路径。

例子

const { normalize,join } = require('path');

console.log(join('/foo', 'bar', 'baz/asdf', 'quux', '..'));
console.log(join('/usr','../local','bin/'));

结果如图

path_join.png

3,path.resolve([...paths])

path.resolve() 方法会把一个路径或路径片段的序列解析为一个绝对路径。

例子

const { resolve } = require('path');

console.log(resolve('./'));
console.log(resolve('/foo/bar', './baz'));
console.log(resolve('/foo/bar', '/tmp/file/'));

结果如图

初学node,你必须懂的几个api_第2张图片
path_resolve.png

4,basename:文件名;extname:文件的拓展名;dirnam:目录名文件所在的路径

例子

const { dirname,extname,basename } = require('path');

const filePath = '/usr/local/bin/no.txt';

console.log(dirname(filePath));   // '/usr/local/bin'
console.log(extname(filePath));   // '.txt'
console.log(basename(filePath));  // 'no.txt'

结果如图

pathName.png

5,path.parsepath.format

path.parse() 方法返回一个对象,对象的属性表示 path 的元素。返回的对象有以下属性:rootdirbaseextname

path.format() 方法会从一个对象返回一个路径字符串。 与 path.parse() 相反。

例子

const { parse,format } = require('path');
const filePath = '/usr/local/bin/node_module/package.json';
const ret = parse(filePath);

console.log(ret)  
console.log(format(ret));

结果如图

初学node,你必须懂的几个api_第3张图片
parse_format.png

需要注意的点

pathObject 提供的属性有组合时,有些属性的优先级比其他的高:

  • 如果提供了 pathObject.dir,则 pathObject.root 会被忽略
  • 如果提供了 pathObject.base 存在,则 pathObject.extpathObject.name 会被忽略
//1, 如果提供了 `dir`、`root` 和 `base`,则返回 `${dir}${path.sep}${base}`。
// `root` 会被忽略。
path.format({
  root: '/ignored',
  dir: '/home/user/dir',
  base: 'file.txt'
});
// 返回: '/home/user/dir/file.txt'

// 2,如果没有指定 `dir`,则 `root` 会被使用。
// 如果只提供了 `root` 或 `dir` 等于 `root`,则平台的分隔符不会被包含。
// `ext` 会被忽略。
path.format({
  root: '/',
  base: 'file.txt',
  ext: 'ignored'
});
// 返回: '/file.txt'

// 3,如果没有指定 `base`,则 `name` + `ext` 会被使用。
path.format({
  root: '/',
  name: 'file',
  ext: '.txt'
});
// 返回: '/file.txt'

6,sepdelimiterwin32posix

delimiter提供平台特定的路径分隔符:

  • Windows 上是 ;
  • POSIX 上是 :

sep提供了平台特定的路径片段分隔符:

  • Windows 上是 \
  • POSIX 上是 /

path.win32 属性提供了 path 方法针对 Windows 的实现;

path.posix 属性提供了 path 方法针对 POSIX 的实现。

例子

// mac下

const { sep,delimiter,win32,posix } = require('path');

console.log('PATH:',process.env.PATH);  // "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

console.log('sep:',sep);      // "/"
console.log('win sep:',win.sep); // "\"

console.log('delimiter:',delimiter); // ":"
console.log('delimiter:',win.delimiter); // ";"

结果如图

初学node,你必须懂的几个api_第4张图片
win.png

7,关于路径的注意点

__dirnameprocess.cwd()path.resolve()三者的区别

例子

//1,在项目的根目录执行:
$ ~/Desktop/node_demo $ node index.js

============代码============
const path = require('path');
const mod = require('./test.js');

console.log(mod.testVar); // 5
console.log('__dirname',__dirname);    // "/Users/fujiawei/Desktop/node_demo"
console.log('process.cwd()',process.cwd());  // "/Users/fujiawei/Desktop/node_demo"
console.log('./',path.resolve('./')); // "/Users/fujiawei/Desktop/node_demo"

===================

//2,在Desktop执行
$ ~/Desktop $ node node_demo/index.js

============代码============
const path = require('path');
const mod = require('./test.js');

console.log(mod.testVar); // 5
console.log('__dirname',__dirname);    // "/Users/fujiawei/Desktop/node_demo"
console.log('process.cwd()',process.cwd());  // "/Users/fujiawei/Desktop"
console.log('./',path.resolve('./')); // "/Users/fujiawei/Desktop"


  • __dirname__filename总是返回文件的绝对路径,即物理磁盘上的路径
  • process.cwd()总是返回执行node命令时所在的文件夹路径,当前在哪里启动的脚本路径
  • ./require方法中总是相对当前文件所在文件夹的路径;在其他的地方和process.cwd()一样,相对node启动文件夹

二,buffer

Buffer处理二进制数据流;实例类似整数数组;大小固定;C++代码在V8堆外分配物理内存

1,Buffer.alloc()

  • size 新建的 Buffer 期望的长度
  • fill 用来预填充新建的 Buffer 的值。 默认: 0
  • encoding 如果 fill 是字符串,则该值是它的字符编码。 默认: 'utf8'

分配一个大小为 size 字节的新建的 Buffer 。 如果 fillundefined ,则该 Buffer 会用 0 填充

例子

var buf1 = Buffer.alloc(10);
console.log(buf1);

结果如图

buffer1.png

例子

var buf1 = Buffer.alloc(10,1);
console.log(buf1);

结果如图

buffer2.png

2,Buffer.allocUnsafe()

分配一个大小为 size 字节的新建的 Buffer 。 如果 size 大于 buffer.constants.MAX_LENGTH 或小于 0,则抛出 RangeError错误。 如果 size 为 0,则创建一个长度为 0 的 Buffer

以这种方式创建的 Buffer 实例的底层内存是未初始化的。 新创建的 Buffer 的内容是未知的,且可能包含敏感数据。 可以使用 buf.fill(0)初始化 Buffer实例为0。

例子

var buf1 = Buffer.allocUnsafe(10);
console.log(buf1);

结果如图

buffer3.png

3,Buffer.from()

  • array

通过一个八位字节的 array 创建一个新的 Buffer

例子

var buf1 = Buffer.from([1,2,3]);
console.log(buf1);

结果如图

buffer4.png

例子

var buf1 = Buffer.from('text'); // 默认utf8
console.log(buf1);
buffer5.png

结果如图

var buf1 = Buffer.from('text', 'base64')
console.log(buf1);
buffer6.png

4,Buffer.byteLength()

  • string 要计算长度的值
  • encoding 如果 string 是字符串,则这是它的字符编码。 默认: 'utf8'
  • 返回: string 包含的字节数

返回一个字符串的实际字节长度。 这与 String.prototype.length 不同,因为那返回字符串的字符数。

例子

var buf1 = Buffer.byteLength('text')
console.log(buf1);   // 4

var buf2 = Buffer.byteLength('测试')
console.log(buf2);   // 6

5,Buffer.isBuffer()

如果 obj 是一个 Buffer 则返回 true ,否则返回 false

var buf1 = Buffer.isBuffer({})
console.log(buf1); // false

var buf2 = Buffer.isBuffer(Buffer.from([1,2,3]))
console.log(buf2); // true

6,Buffer.concat()

  • list 要合并的 BufferUint8Array实例的数组
  • totalLength 合并时 listBuffer 实例的总长度
  • 返回: buffer

返回一个合并了 list 中所有 Buffer 实例的新建的 Buffer

例子

const buf1 = Buffer.from('this ');
const buf2 = Buffer.from('is ');
const buf3 = Buffer.from('good!');

var buf = Buffer.concat([buf1,buf2,buf3])
console.log(buf.toString());  

结果如图

bufferconcat.png
接下来是buffer的实例方法:

7,buf.length

返回 buf 在字节数上分配的内存量。 注意,这并不一定反映 buf 内可用的数据量。

例子

var buf = Buffer.from('good!')
console.log(buf.length); // 5

8,buf.toString()

buffer转化为字符串

例子

var buf = Buffer.from('good!')
console.log(buf.toString());            // good!
console.log(buf.toString('base64'));    // Z29vZCE=

9,buf.fill()

填充buffer

  • value 用来填充 buf 的值。
  • offset 开始填充 buf 前要跳过的字节数。默认: 0
  • end 结束填充 buf 的位置(不包含)。默认: buf.length
  • encoding 如果 value 是一个字符串,则这是它的字符编码。默认: 'utf8'
  • 返回: buf 的引用。

如果未指定 offsetend,则填充整个 buf。 这个简化使得一个 Buffer 的创建与填充可以在一行内完成。

例子

var buf1 = Buffer.allocUnsafe(10);
console.log(buf1)
console.log(buf1.fill(10,2,6)); // good!

结果如图

bufferfill.png

10,buf.equals()

如果 bufotherBuffer 具有完全相同的字节,则返回 true,否则返回 false

例子

var buf4 = Buffer.from('test');
var buf5 = Buffer.from('test');
var buf6 = Buffer.from('test!');

console.log(buf4.equals(buf5));     // true
console.log(buf4.equals(buf6));     // false

11,buf.indexOf()

javascriptindexOf的方法。

例子

var buf4 = Buffer.from('test');
console.log(buf4.indexOf('es'));  // 1
console.log(buf4.indexOf('a'));   // -1

12,buffer 打印例子

一个文字的字符是3,所以会出现乱码。

例子

const buf = Buffer.from('中文字符串!');

for (let i = 0;i < buf.length; i += 5) {
    const b = Buffer.allocUnsafe(5);
    buf.copy(b, 0, i);
    console.log(b.toString());
}

const StringDecoder = require('string_decoder').StringDecoder;

const decoder = new StringDecoder('utf8');

for (let i = 0;i < buf.length; i += 5) {
    const b = Buffer.allocUnsafe(5);
    buf.copy(b, 0, i);
    console.log(decoder.write(b));
}

结果如图

初学node,你必须懂的几个api_第5张图片
打印乱码.png

三,event,事件机制

事件驱动和异步i/o,大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器)。

所有能触发事件的对象都是 EventEmitter 类的实例。 这些对象开放了一个 eventEmitter.on() 函数,允许将一个或多个函数绑定到会被对象触发的命名事件上。 事件名称通常是驼峰式的字符串,但也可以使用任何有效的 JavaScript 属性名。

EventEmitter 对象触发一个事件时,所有绑定在该事件上的函数都被同步地调用。 监听器的返回值会被丢弃。

1,最简单的demo

例子

const EventEmitter = require('events');

class CustomEvent extends EventEmitter {}

const ce = new CustomEvent();

ce.on('test', ()=> {
    console.log('this is test');
})

setInterval(()=>{
    ce.emit('test');
},500);

结果如图

初学node,你必须懂的几个api_第6张图片
event1.gif

2,定制抛出错误的事件处理程序

例子

const EventEmitter = require('events');

class CustomEvent extends EventEmitter {}

const ce = new CustomEvent();

ce.on('error', (err,time) => {
    console.log(err);
    console.log(time);

})

ce.emit('error',new Error('失败了'), Date.now()); // 第二个是穿给时间的参数

结果如图

初学node,你必须懂的几个api_第7张图片
event2.png

3,只响应一次事件

例子

const EventEmitter = require('events');
class CustomEvent extends EventEmitter {}
const ce = new CustomEvent();

ce.once('test', () => {
    console.log('test event');
})

setInterval(()=>{
    ce.emit('test');
},500);

结果如图

初学node,你必须懂的几个api_第8张图片
event3.gif

4,删除事件

分为删除事件的具体的某一个方法:ce.removeListener(事件名,具体方法)

例子

const EventEmitter = require('events');
class CustomEvent extends EventEmitter {}
const ce = new CustomEvent();

function fn1 () {
    console.log('fn1');
}

function fn2 () {
    console.log('fn2');
}

ce.on('test',fn1);
ce.on('test',fn2);

setInterval(()=>{
    ce.emit('test');
},500);

setInterval(()=>{
    // 移除某一个方法
    ce.removeListener('test',fn1);  // 删除test事件的fn1函数
},1500);

结果如图

初学node,你必须懂的几个api_第9张图片
event4.gif

删除事件所有方法,即删除事件:ce.removeAllListeners(事件名)

例子

const EventEmitter = require('events');
class CustomEvent extends EventEmitter {}
const ce = new CustomEvent();

function fn1 () {
    console.log('fn1');
}

function fn2 () {
    console.log('fn2');
}

ce.on('test',fn1);
ce.on('test',fn2);

setInterval(()=>{
    ce.emit('test');
},500);

setInterval(()=>{
    // 移除所有的事件
    ce.removeAllListeners('test');
},1500);

结果如图

初学node,你必须懂的几个api_第10张图片
event6.gif

四,fs:文件系统

文件 I/O 是对标准 POSIX 函数的简单封装。 通过 require('fs') 使用该模块。 所有的方法都有异步和同步的形式。

异步方法的最后一个参数都是一个回调函数。 传给回调函数的参数取决于具体方法,但回调函数的第一个参数都会保留给异常。 如果操作成功完成,则第一个参数会是 nullundefined

1,fs.readFile:读文件

例子

fs.readFile('./index.js',(err,data) => {
    if(err) throw err;
    console.log(data);
});

结果如图

读文件.png

buffer变成string

fs.readFile('./index.js','utf8', (err,data) => {
    if(err) throw err;
    console.log(data);
});

结果如图

初学node,你必须懂的几个api_第11张图片
bufferstring.png

报错:找不到相应的文件夹的时候

例子

fs.readFile('./index.jss','utf8', (err,data) => {
    if(err) throw err;
    console.log(data);
});

结果如图

初学node,你必须懂的几个api_第12张图片
报错.png

同步读文件

const data = fs.readFileSync('./test.js','utf8');
console.log(data);

结果如图

初学node,你必须懂的几个api_第13张图片
同步.png

2,写文件:fs.writeFile

例子

fs.writeFile('./test1.js','this is test','utf8',(err) => {
    if(err) throw err;
    console.log('done');
});

结果如图

初学node,你必须懂的几个api_第14张图片
写文件1.png

buffer写入到文件中去

const content = Buffer.from('this is test');

fs.writeFile('./test1.js', content, (err) => {
    if(err) throw err;
    console.log('done');
});

结果如图

写文件2.png

3,文件信息:fs.stat

返回的stats有判断是否为文件和是否为文件夹的方法;

fs.stat('./index.js',(err, stats) => {
    if(err) throw err;
    
    console.log("是否为文件:",stats.isFile());   // 是否为文件
    console.log("是否为文件夹:",stats.isDirectory());  // 是否为文件夹
    console.log("stats详细信息:",stats);
});

结果如图

初学node,你必须懂的几个api_第15张图片
信息1.png
查找文件是否存在
fs.stat('./index.jsf',(err, stats) => {
    if(err) {
        console.log('文件不存在');
        return;
    };
    
    console.log(stats.isFile());   // 是否为文件
    console.log(stats.isDirectory());  // 是否为文件夹
    console.log(stats);
});

结果如图

信息2.png

4,重命名:fs.rename:参数是要改名字的文件,需要修改成的名字,以及回调函数。

例子

fs.rename('./test1.js','test.txt', (err) => {
    if(err) {
        if(err) throw err;
    };
    console.log('done');
});

5,删除fs.unlink

例子

fs.unlink('./test.txt', (err) => {
    if(err) throw err;
    console.log('done');
});

6,查找文件夹fs.readdir

fs.readdir('./', (err,files) => {
    if(err) throw err;
    console.log(files);
});

结果如图

初学node,你必须懂的几个api_第16张图片
查找文件夹.png

7,创建文件夹fs.mkdir

fs.mkdir('aaaa', (err) => {
    if(err) throw err;
});

8,删除文件夹fs.rmdir

fs.rmdir('aaaa', (err) => {
    if(err) throw err;
});

9,监视文件的变化fs.watch,会监视每一次文件的变化,以及变化的文件名。

fs.watch('./', {
    recursive:true //是否递归
}, (eventType, filename) => { // 变化类型与变化文件名
    console.log(eventType, filename);
});

结果如图

初学node,你必须懂的几个api_第17张图片
watch.png

10,比较复杂的,stream是流的意思,方向与数据是条件,用到的场景看电影等

fs.createReadStream读流,pipe控制流的方向,fs.createWriteStream是创建一个流,并可以向里面写数据,这里模拟异步的方式,当随机数小于7的时候我们就往text.txt中写数据。

例子

// 创建一个stream。
const rs = fs.createReadStream('./test.js');

rs.pipe(process.stdout);// 控制方向

// 开始写stream,创建一个stream。
const ws = fs.createWriteStream('./text.txt');

const tid = setInterval(() => {
    const num = parseInt(Math.random() * 10 );
    console.log(num);
    if(num < 7) {
        ws.write(num + '');
    } else {
        clearInterval(tid);
        ws.end();
    }
}, 200);

ws.on('finish',() => {
    console.log('done');
})

结果如图

初学node,你必须懂的几个api_第18张图片
stream.png

写入到text.txt的值

初学node,你必须懂的几个api_第19张图片
stream2.png

11,解决回调地狱,我们使用promiseasync await解决

例子

const promiseify = require('util').promisify;

var read = promiseify(fs.readFile);

read('./fs.js').then(data => {
    console.log(data.toString());
}).catch(ex => {
    console.log(ex)
})

结果如图

初学node,你必须懂的几个api_第20张图片
promise.png
async await: async functionnode > 8.0 就可以使用。
const promiseify = require('util').promisify;

var read = promiseify(fs.readFile);

// 

async function  test() {
    try{
        const content = await read('./fs.js');
        console.log(content.toString());
    } catch (ex) {
        console.log(ex)
    }
}

test()

结果如图

初学node,你必须懂的几个api_第21张图片
async function.png

五,参考文件

此篇文章是参考了Node.js中文网,自己写的一些apidemo

希望这篇文章对大家能有帮助,来自一个奔跑在前端路上的前端小白。

你可能感兴趣的:(初学node,你必须懂的几个api)