path 模块提供了一些实用函数,用于处理文件和目录的路径。由于不同操作系统(Windows、Linux、macOS)的路径分隔符不同,path 模块能够帮助我们以跨平台的方式安全地操作路径。本章将详细介绍 path 模块的常用方法和最佳实践。
path 是 Node.js 的核心模块,无需安装,直接引入即可使用:
const path = require('path');
不同平台使用的路径分隔符不同:
\ 作为路径分隔符,但也接受正斜杠 /。/。path 模块提供了两个属性:
path.sep:当前平台的文件路径分隔符(Windows 上为 \,POSIX 上为 /)。path.delimiter:当前平台的环境变量路径分隔符(Windows 上为 ;,POSIX 上为 :)。console.log('路径分隔符:', path.sep);
console.log('环境变量分隔符:', path.delimiter);
path.join() 将多个路径片段拼接成一个完整的路径,它会根据当前平台自动添加正确的分隔符,并规范化生成的路径。
const fullPath = path.join('/users', 'node', 'app.js');
console.log(fullPath);
// POSIX 输出: /users/node/app.js
// Windows 输出: \users\node\app.js
path.join() 还会处理多余的斜杠和 ..、. 等:
console.log(path.join('/users', 'node', '..', 'app.js'));
// POSIX 输出: /users/app.js
path.resolve() 将一系列路径或路径片段解析为绝对路径。它的处理逻辑是:从右向左组合路径,直到构造出一个绝对路径。如果组合后仍不是绝对路径,则加上当前工作目录。
console.log(path.resolve('app.js'));
// 输出当前工作目录 + app.js,例如 /home/user/project/app.js
console.log(path.resolve('/users', 'node', 'app.js'));
// 输出 /users/node/app.js
console.log(path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif'));
// 如果当前工作目录是 /home/user/project,则输出 /home/user/project/wwwroot/static_files/gif/image.gif
path.resolve() 不会检查路径是否存在,它只是进行字符串运算。
返回路径的最后一部分(文件名),可选地去除扩展名。
const filePath = '/users/node/app.js';
console.log(path.basename(filePath)); // 'app.js'
console.log(path.basename(filePath, '.js')); // 'app'
返回路径的目录部分。
console.log(path.dirname('/users/node/app.js')); // '/users/node'
返回路径中文件的扩展名(包含点)。如果没有扩展名则返回空字符串。
console.log(path.extname('index.html')); // '.html'
console.log(path.extname('app.js')); // '.js'
console.log(path.extname('README.md')); // '.md'
console.log(path.extname('file.')); // '.'
console.log(path.extname('file')); // ''
path.parse() 将路径字符串解析为一个包含以下属性的对象:
root:根目录(如 / 或 C:\)dir:目录路径base:文件名(包含扩展名)name:文件名(不含扩展名)ext:扩展名(包含点)const parsed = path.parse('/users/node/app.js');
console.log(parsed);
/* 输出(POSIX):
{
root: '/',
dir: '/users/node',
base: 'app.js',
name: 'app',
ext: '.js'
}
*/
path.format() 与 parse 相反,从一个对象生成路径字符串。
const obj = {
dir: '/users/node',
name: 'app',
ext: '.js'
};
console.log(path.format(obj)); // '/users/node/app.js'
path.normalize() 规范化给定的路径,解析 .. 和 . 片段,并去除多余的斜杠。
console.log(path.normalize('/users//node/../app.js'));
// '/users/app.js'
path.relative() 返回从第一个路径到第二个路径的相对路径。如果两个路径相同,返回空字符串。
const from = '/users/node/app.js';
const to = '/users/node/README.md';
console.log(path.relative(from, to)); // '../README.md'
path 模块默认根据当前操作系统提供对应的方法。但你可以显式使用 path.posix 或 path.win32 来强制使用特定平台的实现。例如,即使你在 Windows 上,也可以处理 POSIX 风格的路径:
const posixPath = path.posix.join('users', 'node', 'app.js');
console.log(posixPath); // 'users/node/app.js'
const winPath = path.win32.join('users', 'node', 'app.js');
console.log(winPath); // 'users\\node\\app.js'
const path = require('path');
const dir = 'uploads';
const filename = 'profile.jpg';
const filePath = path.join(__dirname, dir, filename);
console.log(filePath); // 绝对路径,跨平台安全
function isImage(file) {
const ext = path.extname(file).toLowerCase();
return ['.jpg', '.jpeg', '.png', '.gif', '.bmp'].includes(ext);
}
console.log(isImage('photo.JPG')); // true
const filename = path.basename('/path/to/file.txt', '.txt');
console.log(filename); // 'file'
在 Node.js 模块中,__dirname 和 __filename 分别表示当前模块的目录绝对路径和文件绝对路径。它们与 path 模块结合使用非常方便:
const path = require('path');
console.log(__dirname); // 当前文件所在目录
console.log(__filename); // 当前文件绝对路径
console.log(path.basename(__filename)); // 当前文件名
// 构建相对于当前文件的路径
const configPath = path.join(__dirname, 'config', 'settings.json');
path 模块只处理路径字符串,不检查路径是否存在或指向有效文件。path.resolve() 可能会返回以驱动器号开头的路径,例如 C:\project\file.js。path.join() 或 path.resolve() 时,如果参数中包含绝对路径,前面的参数会被忽略(取决于具体方法)。path.resolve() 并结合检查,防止目录遍历攻击(如包含 ../ 的恶意路径)。例如,可以使用 path.resolve(baseDir, userInput) 后检查结果是否以 baseDir 开头。
path 模块是 Node.js 中处理文件系统路径的必备工具。通过本章的学习,你应该掌握了路径拼接、解析、格式化、规范化等核心方法,以及如何利用这些方法编写跨平台的安全代码。在后续章节中,我们将结合 fs 和 path 模块进行更复杂的文件操作。