NodeJS(三):基础 API

2020-09-14  本文已影响0人  林ze宏

目录

1 path

1.1 简介

处理路径相关的:normalize、join、resolve


处理名称相关的:basename 、extname 、dirname


处理路径相关的:parse、format


操作系统相关的:sep、delimiter 、win32、posix


1.2 示例

const { normalize } = require("path");
console.log(normalize("usr/local//bin/no.txt"));
console.log(normalize("usr/local/../bin/no.txt"));

输出:
usr\local\bin\no.txt
usr\bin\no.txt
const { join } = require("path");
console.log(join("usr/", "local", "/bin/"));
console.log(join("usr/", "\\local/", "/bin/"));

输出:
usr\local\bin\
usr\local\bin\
const { resolve } = require("path");
console.log(resolve("./"));

输出:
C:\E\test\node-test
const { basename, extname, dirname } = require("path");
const filePath = "usr/local/bin/no.txt";
console.log(basename(filePath));
console.log(extname(filePath));
console.log(dirname(filePath));

输出:
no.txt
.txt
usr/local/bin
const { parse, format } = require("path");
const filePath = "usr/local/bin/no.txt";
const ret = parse(filePath);
console.log(ret);
console.log(format(ret));

输出:
{ root: '',
  dir: 'usr/local/bin',
  base: 'no.txt',
  ext: '.txt',
  name: 'no' }
usr/local/bin\no.txt

对几个容易混淆的路径相关命令说明:

const path = require('path');

console.log('__dirname          ', __dirname);
console.log('process.cwd()      ', process.cwd());
console.log('./                 ', path.resolve('./'));


如果执行命令路径为:C:\E\教程\node\node>src> node test.js
输出:
__dirname              C:\E\教程\node\node\src
process.cwd()          C:\E\教程\node\node\src
./                     C:\E\教程\node\node\src


如果执行命令路径为:C:\E\教程\node\node> node src/test.js
输出:
__dirname              C:\E\教程\node\node\src
process.cwd()          C:\E\教程\node\node
./                     C:\E\教程\node\node

总结:

2 Buffer

Buffer 类在 Node.js 中是一个全局变量。


const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(10, 1);
const buf3 = Buffer.from([1, 2, 3]);
const buf4 = Buffer.from("test"); // 默认 utf-8
const buf5 = Buffer.from("test", "base64"); // 使用 base64 编码
console.log(buf1);
console.log(buf2);
console.log(buf3);
console.log(buf4);
console.log(buf5);

输出:
<Buffer 00 00 00 00 00 00 00 00 00 00>
<Buffer 01 01 01 01 01 01 01 01 01 01>
<Buffer 01 02 03>
<Buffer 74 65 73 74>
<Buffer b5 eb 2d>
console.log(Buffer.byteLength("test"));
console.log(Buffer.byteLength("测试"));

输出:
4
6
console.log(Buffer.isBuffer({}));
console.log(Buffer.isBuffer(Buffer.from([1, 2, 3])));

输出:
false
true
const buf1 = Buffer.from("this ");
const buf2 = Buffer.from("is ");
const buf3 = Buffer.from("a ");
const buf4 = Buffer.from("test ");
const buf5 = Buffer.from("!");

const buf = Buffer.concat([buf1, buf2, buf3, buf4, buf5]);
console.log(buf);

输出:
<Buffer 74 68 69 73 20 69 73 20 61 20 74 65 73 74 20 21>
this is a test !
length:Buffer 实例里面内容的长度。

const buf = Buffer.from("this is node test!");
console.log(buf.length);

输出:
18
toString:Buffer 内容转化为 String,可以指定编码,默认为 utf-8

const buf = Buffer.from("this is node test!");
console.log(buf);
console.log(buf.toString("base64"));
console.log(buf.toString());

输出:
<Buffer 74 68 69 73 20 69 73 20 6e 6f 64 65 20 74 65 73 74 21>
dGhpcyBpcyBub2RlIHRlc3Qh
this is node test!
fill:Buffer 填充的内容,默认为 0。

const buf = Buffer.alloc(10);
console.log(buf);
console.log(buf.fill(1));

输出:
<Buffer 00 00 00 00 00 00 00 00 00 00>
<Buffer 01 01 01 01 01 01 01 01 01 01>
equals:Buffer 实例中内容是否相等

const buf1 = Buffer.from("test");
const buf2 = Buffer.from("test");
const buf3 = Buffer.from("test1");
console.log(buf1.equals(buf2));
console.log(buf1.equals(buf3));

输出:
true
false

indexOf:跟数组的方法一样,找不到返回 -1,找到匹配第一个位置的下标。

const buf = Buffer.from("test");
console.log(buf.indexOf("es"));
console.log(buf.indexOf("esa"));

输出:
1
-1

const buf1 = Buffer.from([1, 2, 3]);
console.log(buf1.indexOf(2));
console.log(buf1.indexOf("esa"));

输出:
1
-1

copy:复制
中文乱码问题:
const buf = Buffer.from("中文乱码");
for (let i = 0; i < buf.length; i += 5) {
  const b = Buffer.alloc(5);
  buf.copy(b, 0, i); 
  // buf 内容从 0 到 i,复制到 b。因为一个中文占 6 个字符,
  // b 的大小只有 5,肯定会出现乱码。
  console.log(b.toString());
}

输出:
中�
�乱�
��


解决中文乱码问题:
const { StringDecoder } = require("string_decoder"); // 内部模块
const decoder = new StringDecoder('utf8');

const buf = Buffer.from("中文乱码");
for (let i = 0; i < buf.length; i += 5) {
  const b = Buffer.alloc(5);
  buf.copy(b, 0, i);
  console.log(decoder.write(b)); // 使用 decoder write方法来打印
}

输出:
中
文乱
码

3 events

简单实例:

const EventEmitter = require("events");

class CustomEvent extends EventEmitter { // 必须继承 EventEmitter,才能监听事件

}

const ce = new CustomEvent();

ce.on("test", () => { // 监听 test
  console.log("this is a test");
})

ce.emit("test"); // 触发 test 函数

输出:
this is a test

实例2:有参数

const EventEmitter = require("events");

class CustomEvent extends EventEmitter { // 必须继承 EventEmitter,才能监听事件

}

const ce = new CustomEvent();

ce.on("error", (err, timer) => { // 监听 error
  console.log("this is a err", err);
  console.log("this is a timer", timer);
})

ce.emit("error", new Error("出错啦!"), Date.now()); // 触发 error 函数


输出:
this is a err Error: 出错啦!
    at Object.<anonymous> (C:\E\test\node-test\index.js:14:18)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:279:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:696:3)
this is a timer 1571751854397

实例3

const EventEmitter = require("events");

class CustomEvent extends EventEmitter { // 必须继承 EventEmitter,才能监听事件

}

const ce = new CustomEvent();

ce.once("test", () => { // 监听 test,相比 on,once 只触发一次
  console.log("this is a test");
})
setInterval(() => {
  ce.emit("test");
}, 500)

实例4

const EventEmitter = require("events");

class CustomEvent extends EventEmitter { // 必须继承 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);

输出:
fn1
fn2
fn1
fn2
fn1
fn2
fn1
fn2
fn1
.
.
.
新增移除监听

const EventEmitter = require("events");

class CustomEvent extends EventEmitter { // 必须继承 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);

setTimeout(() => {
  ce.removeListener('test', fn1); // 移除单个处理函数

  // ce.removeAllListeners('test'); // 移除所有
}, 1500)


4 fs

常见的方法有:
readFile、writerFile、stat、rename、unlink、readdir、mkdir、rmdir、watch、createReadStream、createWriteStream、pipe、promisify、fsPromises 等等。

const fs = require('fs');

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

执行:C:\E\教程\node\node>node test.js
输出:(默认输出 Buffer)
<Buffer 63 6f 6e 73 74 20 66 73 20 3d 20 72 65 71 75 69 72 65 28 27 66 73 27 29
3b 0a 0a 66 73 2e 72 65 61 64 46 69 6c 65 28 27 2e 2f 74 65 73 74 2e 6a 73 27 ... 65 more bytes>


通过配置参数,输出 字符串:

const fs = require('fs');

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

或者:

const fs = require('fs');

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


输出:(读取本身文件)
const fs = require('fs');

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

const fs = require('fs');

fs.writeFile('./test.js', "这是写入文件的内容", "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});

const fs = require('fs');

fs.stat('./test.js2', (err, stats) => {
  // if (err) throw err;
  if (err) {
    console.log("文件或目录不存在");
    return;
  }

  if (stats.isFile()) {
    console.log("文件:", stats.isFile());
  }

  if (stats.isDirectory()) {
    console.log("目录:", stats.isDirectory());
  }
});

const fs = require('fs');

fs.rename('./test.js', './reNameTest2.js', (err) => {
  if (err) throw err;
});

const fs = require('fs');

fs.unlink('./a.js', (err) => {
  if (err) throw err;
});

const fs = require('fs');

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

输出:
[ '404.html',
  'aa',
  'handle.js',
  'index.html',
  'main.js',
  'router.js',
  'server.js',
  'test.js',
  'test2.js',
  'test2.txt' ]

const fs = require('fs');

fs.mkdir('./vv', (err, data) => {
  if (err) throw err;
  console.log(data);
});

const fs = require('fs');

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

扩展,删除文件夹下面的所有内容:

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

/**
 *
 * @desc 异步深度循环删除目录
 * @param {string} dir 需要删除的目录
 * @param {function} callback 回调函数
 *
 * 实现思路:
 * 1.读取文件目录拿到当前目录所有的files
 * 2.调用next方法,并从0开始遍历files
 * 3.遍历结束,调用callbanck
 */
function rmdir(dir, callback) {
  fs.readdir(dir, (err, files) => {
    /**
     * @desc 内部循环遍历使用的工具函数
     * @param {Number} index 表示读取files的下标
     */
    function next(index) {
      // 如果index 等于当前files的时候说明循环遍历已经完毕,可以删除dir,并且调用callback
      if (index == files.length) return fs.rmdir(dir, callback)
      // 如果文件还没有遍历结束的话,继续拼接新路径,使用fs.stat读取该路径
      let newPath = path.join(dir, files[index])
      // 读取文件,判断是文件还是文件目录

      fs.stat(newPath, (err, stat) => {
        if (stat.isDirectory()) {
          // 因为我们这里是深度循环,也就是说遍历玩files[index]的目录以后,才会去遍历files[index+1]
          // 所以在这里直接继续调用rmdir,然后把循环下一个文件的调用放在当前调用的callback中
          rmdir(newPath, () => next(index + 1))
        } else {
          // 如果是文件,则直接删除该文件,然后在回调函数中调用遍历nextf方法,并且index+1传进去
          fs.unlink(newPath, () => next(index + 1))
        }
      })
    }
    next(0)
  })
}

rmdir('./vv', () => { console.log('文件删除完毕') })

const fs = require('fs');

fs.watch('./aa', {
  recursive: true, // 指示应该监视所有子目录
}, (eventType, filename) => {
  console.log(eventType, filename);
});


const fs = require("fs");

const rs = fs.createReadStream('./test3.js');   // 文件读取流,如果不存在,报错
const ws = fs.createWriteStream('./test2.js');  // 文件写入流,如果不存在,就创建
// rs.pipe(ws);  // 管道(读完之后,通过管道流入到写入流进行写操作)

rs.on('data', function (chunk) {
  console.log(chunk.length);  // 65536  chunk就是一个Buffer(存放16进制数据的"数组",长度以B字节计算(两个16进制为一个元素))
  ws.write(chunk);    // Node中的Buffer不占用垃圾回收机制中的内存。  Buffer是由C/C++模块维护。  'data'+chunk会在内部自动调用toString()函数。 建议直接返回buffer节省处理字符串的性能开销。
});

rs.on('end', function () {
  console.log('结束啦!');
  ws.end();
});


对于 fs,可以直接使用 fsPromises 模块。

使用 then 方式处理:
const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);
stat('./test.js').then((stats) => {
  console.log(stats.isFile());
  // 使用 `stats`。
}).catch((error) => {
  // 处理错误。
  console.log(error);
});

使用 async 、await 方式处理:
const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);

async function callStat() {
  const stats = await stat('.');
  console.log(`该目录归 ${stats.uid} 拥有`);
}
callStat();

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

const readFile = util.promisify(fs.readFile);

async function test() {
  const data = await readFile('test.js', 'utf8');
  console.log(data);
}
test();

const fsPromises = require('fs').promises;

// 默认情况下将创建或覆盖目标文件。
fsPromises.readFile('test.js', 'utf8').then((data) => {
  console.log(data);
}).catch((ex) => {
  console.log(ex)
});

const fsPromises = require('fs').promises;

// 默认情况下将创建或覆盖目标文件。
fsPromises.copyFile('源文件.txt', '目标文件.txt')
  .then(() => console.log('源文件已拷贝到目标文件'))
  .catch(() => console.log('该文件无法拷贝'));

fsPromises,使用 async 、await :

const fsPromises = require('fs').promises;

async function test(params) {
  try {
    const content = await fsPromises.readFile('test.js', 'utf8');
    console.log(content);
  } catch (error) {
    console.log(error);
  }
}
test();

5 process

process 是 global 全局对象下的属性,所以,可以直接使用,不用通过 require 引入。

常见的方法有:
argv、argv0、execArgv、execPath、env、cwd

const { argv, argv0, execArgv, execPath } = process;

argv.forEach(item => {
  console.log(item);
});
输出:
C:\D\node-v11.11.0-win-x64\node-v11.11.0-win-x64\node.exe
C:\E\教程\node\node\src\test.js
-a=1
--b=2
cc


console.log(argv0);
输出:node


console.log(execArgv);
输出:[ '--inspect' ]


console.log(execPath);
输出:C:\D\node-v11.11.0-win-x64\node-v11.11.0-win-x64\node.exe


执行:C:\E\教程\node\node>node --inspect  src/test.js -a=1 --b=2 cc
const { env } = process;

console.log(env);

输出:
{ ALLUSERSPROFILE: 'C:\\ProgramData',
  ANDROID_HOME: 'C:\\D\\Android\\android-sdk-windows',
  APPDATA: 'C:\\Users\\65401\\AppData\\Roaming',
  'asl.log': 'Destination=file',
  CLASSPATH:
   '.;C:\\D\\jdk1.8\\lib\\dt.jar;C:\\D\\jdk1.8\\lib\\tools.jar;',
  CommonProgramFiles: 'C:\\Program Files\\Common Files',
  'CommonProgramFiles(x86)': 'C:\\Program Files (x86)\\Common Files',
  CommonProgramW6432: 'C:\\Program Files\\Common Files',
  COMPUTERNAME: 'DESKTOP-TBQ5E1Q',
  ComSpec: 'C:\\WINDOWS\\system32\\cmd.exe',
  DriverData: 'C:\\Windows\\System32\\Drivers\\DriverData',
  FPS_BROWSER_APP_PROFILE_STRING: 'Internet Explorer',
  FPS_BROWSER_USER_PROFILE_STRING: 'Default',
  HOMEDRIVE: 'C:',
  HOMEPATH: '\\Users\\65401',
  JAVA_HOME: 'C:\\D\\jdk1.8',
  LANG: 'en_US.UTF-8',
  LOCALAPPDATA: 'C:\\Users\\65401\\AppData\\Local',
  LOGONSERVER: '\\\\DESKTOP-TBQ5E1Q',
  NUMBER_OF_PROCESSORS: '4',
  OneDrive: 'C:\\Users\\65401\\OneDrive',
  OneDriveConsumer: 'C:\\Users\\65401\\OneDrive',
  OS: 'Windows_NT',
  Path:
   'C:\\Program Files (x86)\\Intel\\iCLS Client\\;C:\\Program Files\\Intel\\iCLS Client\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\D\\node-v11.11.0-win-x64\\node-v11.11.0-win-x64;C:\\D\\Redis;"C:\\D\\jdk1.8\\bin;C:\\D\\jdk1.8\\jre\\bin;";C:\\Program Files\\Git\\cmd;C:\\Program Files (x86)\\MySQL\\MySQL Utilities 1.6\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Python27\\;C:\\D\\jdk1.8\\bin;C:\\D\\Android\\android-sdk-windows\\tools;C:\\D\\Android\\android-sdk-windows\\platform-tools;C:\\Python27\\Scripts;C:\\Program Files\\Intel\\WiFi\\bin\\;C:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C:\\Users\\65401\\AppData\\Local\\Yarn\\bin;C:\\Program Files (x86)\\Intel\\iCLS Client\\;C:\\Program Files\\Intel\\iCLS Client\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C:\\Program Files\\Intel\\WiFi\\bin\\;C:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C:\\D\\node-v11.11.0-win-x64\\node-v11.11.0-win-x64;C:\\D\\Redis;"C:\\D\\IDE\\jdk1.7\\bin;C:\\D\\IDE\\jdk1.7\\jre\\bin;";C:\\Program Files\\Git\\cmd;C:\\Program Files (x86)\\MySQL\\MySQL Utilities
1.6\\;C:\\Users\\65401\\AppData\\Local\\Microsoft\\WindowsApps;C:\\D\\Microsoft VS Code\\bin;C:\\D\\SSH;C:\\Users\\65401\\AppData\\Local\\Turbo\\Cmd\\;C:\\Users\\65401\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\65401\\AppData\\Local\\Pandoc\\;C:\\Users\\65401\\AppData\\Roaming\\npm;C:\\Users\\65401\\AppData\\Local\\Yarn\\bin;',
  PATHEXT: '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC',
  PROCESSOR_ARCHITECTURE: 'AMD64',
  PROCESSOR_IDENTIFIER: 'Intel64 Family 6 Model 142 Stepping 9, GenuineIntel',
  PROCESSOR_LEVEL: '6',
  PROCESSOR_REVISION: '8e09',
  ProgramData: 'C:\\ProgramData',
  ProgramFiles: 'C:\\Program Files',
  'ProgramFiles(x86)': 'C:\\Program Files (x86)',
  ProgramW6432: 'C:\\Program Files',
  PROMPT: '$P$G',
  PSModulePath:
   'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules',
  PUBLIC: 'C:\\Users\\Public',
  SESSIONNAME: 'Console',
  SystemDrive: 'C:',
  SystemRoot: 'C:\\WINDOWS',
  TEMP: 'C:\\Users\\65401\\AppData\\Local\\Temp',
  TERM_PROGRAM: 'vscode',
  TERM_PROGRAM_VERSION: '1.20.1',
  TMP: 'C:\\Users\\65401\\AppData\\Local\\Temp',
  USERDOMAIN: 'DESKTOP-TBQ5E1Q',
  USERDOMAIN_ROAMINGPROFILE: 'DESKTOP-TBQ5E1Q',
  USERNAME: '65401',
  USERPROFILE: 'C:\\Users\\65401',
  VBOX_MSI_INSTALL_PATH: 'C:\\D\\Genymotion\\VirtualBox\\',
  VSCODE_CWD: 'C:\\D\\Microsoft VS Code',
  VSCODE_IPC_HOOK:
   '\\\\.\\pipe\\0f9b2e01495c846f2683e1e9fa734047-1.20.1-main-sock',
  VSCODE_NLS_CONFIG: '{"locale":"zh-cn","availableLanguages":{"*":"zh-cn"}}',
  VSCODE_NODE_CACHED_DATA_DIR_22284:
   'C:\\Users\\65401\\AppData\\Roaming\\Code\\CachedData\\f88bbf9137d24d36d968ea6b2911786bfe103002',
  VSCODE_PID: '22284',
  windir: 'C:\\WINDOWS' }
const { cwd } = process;

console.log(cwd());

当前命令所执行的路径,跟 Linux pwd 命令一样。

如果是在这个路径下执行:C:\E\教程\node\node> node src/test.js
输出:
C:\E\教程\node\node

如果是在这个路径下执行:C:\E\教程\node\node\src> node  test.js
输出:
C:\E\教程\node\node\src
上一篇 下一篇

猜你喜欢

热点阅读