第四章:文件系统与路径操作

作者:Administrator 发布时间: 2026-03-13 阅读量:6 评论数:0

第四章:文件系统与路径操作

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);
}

评论