阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 目录操作

目录操作

作者:陈川 阅读数:62238人阅读 分类: Node.js

文件系统基础

Node.js 提供了 fs 模块来处理文件系统操作。这个模块包含同步和异步两种方法,其中异步方法通常更受欢迎,因为它们不会阻塞事件循环。要使用 fs 模块,首先需要引入它:

const fs = require('fs');
const fsPromises = require('fs').promises; // Promise版本

创建目录

创建目录是目录操作中最基本的任务之一。Node.js 提供了 mkdir()mkdirSync() 方法来实现这一功能。

// 异步创建目录
fs.mkdir('new-directory', (err) => {
  if (err) throw err;
  console.log('目录创建成功');
});

// 同步创建目录
try {
  fs.mkdirSync('new-directory-sync');
  console.log('同步方式目录创建成功');
} catch (err) {
  console.error(err);
}

// 使用Promise创建目录
async function createDir() {
  try {
    await fsPromises.mkdir('new-directory-promise');
    console.log('Promise方式目录创建成功');
  } catch (err) {
    console.error(err);
  }
}
createDir();

递归创建目录

有时候需要创建多层嵌套的目录结构,可以使用 recursive 选项:

// 递归创建目录
fs.mkdir('parent/child/grandchild', { recursive: true }, (err) => {
  if (err) throw err;
  console.log('递归目录创建成功');
});

读取目录内容

读取目录内容是常见的操作,可以使用 readdir() 方法:

// 异步读取目录
fs.readdir('./', (err, files) => {
  if (err) throw err;
  console.log('目录内容:', files);
});

// 同步读取目录
try {
  const files = fs.readdirSync('./');
  console.log('同步方式读取目录内容:', files);
} catch (err) {
  console.error(err);
}

// 使用Promise读取目录
async function readDir() {
  try {
    const files = await fsPromises.readdir('./');
    console.log('Promise方式读取目录内容:', files);
  } catch (err) {
    console.error(err);
  }
}
readDir();

获取目录详细信息

有时需要获取目录的详细信息,如创建时间、修改时间等:

// 获取目录状态
fs.stat('some-directory', (err, stats) => {
  if (err) throw err;
  console.log('是否是目录:', stats.isDirectory());
  console.log('创建时间:', stats.birthtime);
  console.log('修改时间:', stats.mtime);
});

重命名目录

重命名目录可以使用 rename() 方法:

// 重命名目录
fs.rename('old-name', 'new-name', (err) => {
  if (err) throw err;
  console.log('目录重命名成功');
});

删除目录

删除目录有几种不同的方法,取决于目录是否为空:

// 删除空目录
fs.rmdir('empty-directory', (err) => {
  if (err) throw err;
  console.log('空目录删除成功');
});

// 递归删除非空目录
fs.rm('non-empty-directory', { recursive: true }, (err) => {
  if (err) throw err;
  console.log('非空目录删除成功');
});

目录操作实用技巧

检查目录是否存在

function directoryExists(path) {
  try {
    return fs.statSync(path).isDirectory();
  } catch (err) {
    return false;
  }
}

遍历目录树

function walkDir(dir, callback) {
  fs.readdirSync(dir).forEach(f => {
    let dirPath = path.join(dir, f);
    let isDirectory = fs.statSync(dirPath).isDirectory();
    isDirectory ? walkDir(dirPath, callback) : callback(path.join(dir, f));
  });
}

walkDir('./', file => console.log(file));

创建临时目录

const os = require('os');
const path = require('path');

const tempDir = path.join(os.tmpdir(), 'my-temp-dir');
fs.mkdirSync(tempDir);

目录操作中的错误处理

正确处理目录操作中的错误非常重要:

fs.readdir('/nonexistent', (err, files) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('目录不存在');
    } else {
      console.error('发生未知错误:', err);
    }
    return;
  }
  console.log(files);
});

性能考虑

在处理大量目录操作时,性能成为一个重要因素:

  1. 同步方法会阻塞事件循环,在性能关键的应用中应避免使用
  2. 批量操作时,考虑使用流或工作队列
  3. 对于频繁访问的目录,可以缓存目录内容
// 使用工作队列处理大量目录操作
const { Worker, isMainThread, workerData } = require('worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename, {
    workerData: { dir: './large-directory' }
  });
} else {
  processDir(workerData.dir);
}

function processDir(dir) {
  // 处理目录的繁重任务
}

跨平台注意事项

不同操作系统对目录的处理有差异:

  1. Windows 使用反斜杠()作为路径分隔符,而Unix使用斜杠(/)
  2. 路径大小写敏感性在不同系统上表现不同
  3. 使用 path 模块处理路径可以避免这些问题
const path = require('path');

// 跨平台路径连接
const fullPath = path.join('dir', 'subdir', 'file.txt');

高级目录监控

Node.js 提供了 fs.watch() 方法来监控目录变化:

// 监控目录变化
const watcher = fs.watch('./watched-dir', (eventType, filename) => {
  console.log(`事件类型: ${eventType}`);
  if (filename) {
    console.log(`文件名: ${filename}`);
  }
});

// 停止监控
setTimeout(() => {
  watcher.close();
}, 10000);

目录操作与流结合

将目录操作与流结合可以高效处理大量文件:

const { Readable } = require('stream');

class DirectoryStream extends Readable {
  constructor(dir) {
    super({ objectMode: true });
    this.dir = dir;
    this.files = fs.readdirSync(dir);
    this.index = 0;
  }
  
  _read() {
    if (this.index < this.files.length) {
      this.push(path.join(this.dir, this.files[this.index++]));
    } else {
      this.push(null);
    }
  }
}

const dirStream = new DirectoryStream('./large-dir');
dirStream.on('data', file => console.log(file));

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌