第四章:文件系统与路径操作
4.1 fs模块基础
同步读写
const fs = require('fs');
// 写入文件(同步)
// 参数1: 文件路径
// 参数2: 写入内容
// 参数3: 编码(可选,默认utf8)
fs.writeFileSync('file.txt', 'Hello, Node.js!');
// 读取文件(同步)
// 参数1: 文件路径
// 参数2: 编码
// 返回: 文件内容
const content = fs.readFileSync('file.txt', 'utf8');
console.log(content); // Hello, Node.js!
// 追加内容(同步)
fs.appendFileSync('file.txt', '\n第二行内容');
// 检查文件是否存在
const exists = fs.existsSync('file.txt');
console.log(exists); // true
// 删除文件
fs.unlinkSync('file.txt');
// 重命名文件
fs.renameSync('old.txt', 'new.txt');
异步读写(回调)
const fs = require('fs');
// 异步写入
fs.writeFile('file.txt', 'Hello', (err) => {
if (err) {
console.error('写入失败:', err);
return;
}
console.log('写入成功');
});
// 异步读取
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) {
console.error('读取失败:', err);
return;
}
console.log('文件内容:', data);
});
// 异步追加
fs.appendFile('file.txt', '\n新内容', (err) => {
if (err) throw err;
console.log('追加成功');
});
// 异步删除
fs.unlink('file.txt', (err) => {
if (err) throw err;
console.log('删除成功');
});
Promise方式
const fs = require('fs').promises;
async function fileOperations() {
try {
// 写入
await fs.writeFile('file.txt', 'Hello, Promise!');
// 读取
const content = await fs.readFile('file.txt', 'utf8');
console.log(content);
// 追加
await fs.appendFile('file.txt', '\n第二行');
// 再次读取
const newContent = await fs.readFile('file.txt', 'utf8');
console.log(newContent);
// 删除
await fs.unlink('file.txt');
} catch (err) {
console.error('操作失败:', err);
}
}
fileOperations();
4.2 目录操作
const fs = require('fs');
const path = require('path');
// 创建目录(同步)
fs.mkdirSync('new-folder');
// 创建多级目录
fs.mkdirSync('a/b/c', { recursive: true });
// 读取目录内容
const files = fs.readdirSync('.');
console.log(files); // ['file1.txt', 'folder', ...]
// 获取文件信息
const stats = fs.statSync('file.txt');
console.log(stats);
// Stats {
// dev: 2049,
// mode: 33188,
// nlink: 1,
// uid: 1000,
// gid: 1000,
// size: 17, // 文件大小(字节)
// atime: ..., // 访问时间
// mtime: ..., // 修改时间
// ctime: ..., // 状态改变时间
// birthtime: ... // 创建时间
// }
// 判断是文件还是目录
console.log(stats.isFile()); // true
console.log(stats.isDirectory()); // false
// 删除目录(空目录)
fs.rmdirSync('empty-folder');
// 删除目录及内容
fs.rmSync('folder', { recursive: true, force: true });
// 重命名目录
fs.renameSync('old-name', 'new-name');
// 监听文件变化
fs.watch('file.txt', (eventType, filename) => {
console.log(`文件 ${filename} 发生 ${eventType} 事件`);
});
// 监听目录
fs.watch('.', { recursive: true }, (eventType, filename) => {
console.log(`目录中 ${filename} 发生 ${eventType} 事件`);
});
4.3 流操作
读取流
const fs = require('fs');
// 创建读取流
const readStream = fs.createReadStream('large-file.txt', {
encoding: 'utf8',
highWaterMark: 1024 // 每次读取1KB
});
// 监听数据事件
readStream.on('data', (chunk) => {
console.log('收到数据块:', chunk.length);
});
// 监听结束事件
readStream.on('end', () => {
console.log('读取完成');
});
// 监听错误
readStream.on('error', (err) => {
console.error('读取错误:', err);
});
// 暂停和恢复
readStream.pause();
setTimeout(() => readStream.resume(), 1000);
写入流
const fs = require('fs');
// 创建写入流
const writeStream = fs.createWriteStream('output.txt');
// 写入数据
writeStream.write('第一行\n');
writeStream.write('第二行\n');
// 结束写入
writeStream.end('最后一行\n');
// 监听完成
writeStream.on('finish', () => {
console.log('写入完成');
});
// 监听错误
writeStream.on('error', (err) => {
console.error('写入错误:', err);
});
管道
const fs = require('fs');
const zlib = require('zlib');
// 简单复制
fs.createReadStream('source.txt')
.pipe(fs.createWriteStream('dest.txt'));
// 压缩文件
fs.createReadStream('file.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('file.txt.gz'));
// 解压文件
fs.createReadStream('file.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('file-unzipped.txt'));
// 链式管道
const readStream = fs.createReadStream('input.txt');
const gzipStream = zlib.createGzip();
const writeStream = fs.createWriteStream('output.txt.gz');
readStream.pipe(gzipStream).pipe(writeStream);
4.4 文件遍历工具
const fs = require('fs').promises;
const path = require('path');
// 递归遍历目录
async function walkDir(dir, callback) {
const files = await fs.readdir(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stat = await fs.stat(filePath);
if (stat.isDirectory()) {
await walkDir(filePath, callback);
} else {
await callback(filePath, stat);
}
}
}
// 使用示例
async function listAllFiles() {
console.log('文件列表:');
await walkDir('.', (filePath, stat) => {
console.log(`${filePath} - ${stat.size} bytes`);
});
}
listAllFiles().catch(console.error);
// 查找特定类型文件
async function findFiles(dir, extension) {
const results = [];
await walkDir(dir, (filePath) => {
if (path.extname(filePath) === extension) {
results.push(filePath);
}
});
return results;
}
// 使用
findFiles('.', '.js').then(files => {
console.log('JS文件:', files);
});
// 复制目录
async function copyDir(src, dest) {
await fs.mkdir(dest, { recursive: true });
const entries = await fs.readdir(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
await copyDir(srcPath, destPath);
} else {
await fs.copyFile(srcPath, destPath);
}
}
}
// 删除目录
async function deleteDir(dir) {
await fs.rm(dir, { recursive: true, force: true });
}
4.5 配置文件操作
const fs = require('fs').promises;
const path = require('path');
// 读取JSON配置
async function loadConfig(configPath) {
try {
const data = await fs.readFile(configPath, 'utf8');
return JSON.parse(data);
} catch (err) {
console.error('加载配置失败:', err);
return null;
}
}
// 保存JSON配置
async function saveConfig(configPath, config) {
try {
const data = JSON.stringify(config, null, 2);
await fs.writeFile(configPath, data);
return true;
} catch (err) {
console.error('保存配置失败:', err);
return false;
}
}
// 使用示例
async function configExample() {
const config = {
app: {
name: 'MyApp',
version: '1.0.0',
port: 3000
},
database: {
host: 'localhost',
port: 3306,
name: 'mydb'
}
};
// 保存配置
await saveConfig('config.json', config);
// 加载配置
const loaded = await loadConfig('config.json');
console.log('配置:', loaded);
}
configExample();
// 环境配置
function loadEnvConfig() {
const env = process.env.NODE_ENV || 'development';
const configPath = path.join(__dirname, 'config', `${env}.json`);
return loadConfig(configPath);
}