1. fs 模块
fs(File System)模块允许对文件系统进行操作,提供了文件读写、文件夹操作等功能。fs 支持同步和异步两种 API。
1.1. 常用方法
读取文件:
异步: fs.readFile()
同步: fs.readFileSync()
写入文件:
异步: fs.writeFile()
同步: fs.writeFileSync()
是否存在:
fs.existsSync()
读取目录:
异步: fs.readdir()
同步: fs.readdirSync()
1.2. 代码示例
异步读取文件:
const fs = require('fs');
// 异步读取文件内容
fs.readFile('./example.txt', 'utf-8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
同步写入文件:
const fs = require('fs');
// 同步写入文件内容
fs.writeFileSync('./example.txt', 'Hello, Node.js!');
console.log('文件已写入');
2. path 模块
path 模块提供了一些实用函数来处理和转换文件路径。它是与操作系统无关的,跨平台时会根据系统自动调整路径格式。
2.1. 常用方法
path.join():将多个路径拼接成一个路径。
path.resolve():将相对路径解析为绝对路径。
path.basename():返回路径的最后一部分文件名。
path.dirname():返回路径的目录部分。
path.extname():返回文件的扩展名。
2.2. 代码示例
const path = require('path');
// 拼接路径
const fullPath = path.join(__dirname, 'files', 'example.txt');
console.log(fullPath); // /Users/.../files/example.txt
// 获取文件名
const fileName = path.basename(fullPath);
console.log(fileName); // example.txt
// 获取扩展名
const ext = path.extname(fullPath);
console.log(ext); // .txt
// 获取绝对路径
const absolutePath = path.resolve('example.txt');
console.log(absolutePath); // /Users/.../example.txt
3. os 模块
os 模块提供了一些与操作系统相关的实用工具函数,可以获取系统信息、用户信息等。
3.1. 常用方法
os.arch():返回操作系统的架构。
os.platform():返回操作系统的平台。
os.cpus():返回系统的 CPU 信息。
os.freemem():返回可用的系统内存。
os.totalmem():返回系统的总内存。
os.homedir():返回当前用户的主目录。
os.uptime():返回系统运行时间,单位秒。
3.2. 代码示例
const os = require('os');
// 获取操作系统架构
console.log(os.arch()); // x64
// 获取操作系统平台
console.log(os.platform()); // darwin (macOS) / linux / win32
// 获取系统 CPU 信息
console.log(os.cpus());
// 获取可用内存和总内存
console.log(`Free memory: ${os.freemem()} bytes`);
console.log(`Total memory: ${os.totalmem()} bytes`);
// 获取用户的主目录
console.log(os.homedir());
// 获取系统运行时间
console.log(`System uptime: ${os.uptime()} seconds`);
4. process 模块
process 模块提供了与当前 Node.js 进程相关的功能,包括获取环境变量、退出进程、与操作系统交互等。
4.1. 进程的常用场景
获取和设置环境变量。
获取命令行参数。
控制进程的生命周期,比如退出、发送信号等。
4.2. 常用属性与方法
process.argv:获取命令行参数。
process.env:访问环境变量。
process.exit():退出当前进程。
process.cwd():获取当前工作目录。
process.memoryUsage():获取进程的内存使用情况。
process.nextTick():将回调放入下一次事件循环中执行。
4.3. 代码示例
获取命令行参数:
// 运行 node app.js arg1 arg2
console.log(process.argv); // ['node', 'app.js', 'arg1', 'arg2']
退出进程:
console.log('即将退出进程');
process.exit(0); // 0 表示成功退出
process.exit(1); // 非零退出码表示出错或异常退出
读取环境变量:
const env = process.env.NODE_ENV || 'development';
console.log(`当前环境是:${env}`);
5. child_process 模块
Node.js 的 child_process 模块提供了创建和管理子进程的功能。它允许从 Node.js 应用程序中执行外部命令、启动其他程序或运行脚本。通过子进程,Node.js 可以在自身的单线程模型中实现并发任务的处理。
5.1. 子进程的常用场景
并行执行任务:当有多个任务需要并行处理时,可以使用 spawn() 或 fork() 来创建多个子进程,从而提高应用的并发能力。
执行外部命令或脚本:使用 exec() 来执行外部的 shell 命令、调用外部工具等。
分离任务:如果一个任务可能导致崩溃或阻塞主进程,可以将其放入子进程中运行,以确保主进程的健壮性。
5.2. 子进程模块的常用方法
exec():用于执行一个 shell 命令,返回标准输出和标准错误,适合短命令执行。
spawn():用于启动一个新的进程,可以与其进行持续的流式通信,适合长时间运行的任务。
fork():专门用于创建新的 Node.js 子进程,并允许在父进程和子进程之间传递消息。
5.3. exec() 方法
exec() 是用来执行简单命令的,比如 shell 命令或其他外部脚本。它适合用于执行短时间内返回结果的命令。
const { exec } = require('child_process');
// 执行一个 shell 命令
exec('ls -l', (error, stdout, stderr) => {
if (error) {
console.error(`执行错误: ${error}`);
return;
}
console.log(`标准输出: ${stdout}`);
console.error(`标准错误: ${stderr}`);
});
在这个例子中,exec() 执行了一个 ls -l 命令来列出当前目录的文件列表。
5.4. spawn() 方法
spawn() 用于创建一个新进程,并且可以通过数据流与这个进程进行通信。spawn() 适合长时间运行的任务或者需要不断与子进程交互的任务。
const { spawn } = require('child_process');
// 启动一个新的进程,执行 `ls -l`
const ls = spawn('ls', ['-l']);
// 监听子进程的标准输出
ls.stdout.on('data', (data) => {
console.log(`标准输出: ${data}`);
});
// 监听子进程的错误输出
ls.stderr.on('data', (data) => {
console.error(`标准错误: ${data}`);
});
// 监听子进程的退出事件
ls.on('close', (code) => {
console.log(`子进程退出,退出码: ${code}`);
});
在这个例子中,spawn() 被用来执行 ls -l 命令,并通过事件监听器处理标准输出、标准错误和进程退出。
5.5. fork() 方法
fork() 是 child_process 中的一个特殊方法,它专门用于创建新的 Node.js 进程,并且允许父子进程之间进行 IPC(进程间通信)。
fork() 启动的子进程是一个独立的 Node.js 进程,且可以通过 message 事件进行消息传递。
假设我们有一个 child.js 文件,内容如下:
// child.js
process.on('message', (msg) => {
console.log(`子进程接收到消息: ${msg}`);
process.send(`你好,父进程!`);
});
然后,我们在父进程中使用 fork() 来启动这个子进程并与它通信:
// main.js
const { fork } = require('child_process');
// 创建一个新的子进程,运行 child.js
const child = fork('./child.js');
// 向子进程发送消息
child.send('你好,子进程!');
// 接收子进程发来的消息
child.on('message', (msg) => {
console.log(`父进程接收到消息: ${msg}`);
});
在这个例子中,父进程启动了 child.js 子进程,并通过 send() 和 message 事件来实现进程间的消息传递。
5.6. spawn() 与 exec() 的区别
exec():
适合执行简单、短命令,如 shell 命令,一次性返回结果。
exec() 将整个命令的输出缓存在内存中,可能会导致内存溢出问题。
spawn():
适合执行长时间运行的任务或需要流式处理数据的任务。
spawn() 是基于数据流的,输出和输入是通过流的方式处理,不会占用大量内存。
5.7. 总结
exec():用于执行外部命令,适合短时间的任务,返回的是标准输出和错误输出。
spawn():适用于长时间运行的任务,支持流式数据传输,可以持续监听输出。
fork():用于创建新的 Node.js 子进程,允许父子进程之间进行消息传递,是多进程并发任务的常用方式。
6. util.promisify
util.promisify 是 Node.js 提供的一个工具函数,它将传统回调风格的异步函数转换为返回 Promise 的函数。这样可以更方便地使用 async/await 来处理异步操作。
6.1. 常用场景
许多 Node.js 核心模块(如 fs)的异步方法使用回调函数,可以使用 util.promisify 将它们转换为 Promise 风格,以便在现代异步代码中使用。
6.2. 示例代码
使用 util.promisify 将 fs.readFile 转换为 Promise 版本。
const fs = require('fs');
const util = require('util');
// 将 fs.readFile 转换为 Promise 风格
const readFile = util.promisify(fs.readFile);
// 使用 async/await 读取文件
(async () => {
try {
const data = await readFile('./example.txt', 'utf-8');
console.log(data);
} catch (error) {
console.error(error);
}
})();
通过 promisify,我们可以轻松将任何基于回调的异步函数转换为返回 Promise 的函数,这使得代码更加现代和简洁。
7. 总结
fs: 用于文件操作,支持同步和异步 API。
path: 提供文件路径处理功能,跨平台支持。
os: 提供操作系统相关信息,如平台、内存、CPU。
process: 与当前 Node.js 进程交互,获取命令行参数、环境变量等。
child_process: 用于创建子进程,执行外部命令或脚本。
util.promisify: 将回调风格的异步函数转换为 Promise,便于使用 async/await。