Bootstrap

node.js基础学习-fs模块-文件操作(六)

一、前言

fs模块是 Node.js 内置的文件系统(File System)模块,它提供了一系列用于与文件系统进行交互的方法。通过fs模块,可以对文件或目录进行读取、写入、删除、重命名、查询状态等操作,这使得 Node.js 能够很好地处理本地文件相关的任务。

二、常用方法

1. 读取文件

fs.readFile():这是一种异步读取文件内容的方法。它接受文件路径、编码方式(可选)和回调函数作为参数。例如:

const fs = require('fs');
const file_path = 'example.txt';
fs.readFile(file_path, 'utf8', (err, data) => {
  if (err) {
    console.error('读取文件出错:', err);
  } else {
    console.log('文件内容:', data);
  }
});

在这个例子中,fs.readFile()尝试以utf8编码读取example.txt文件。如果读取过程中出现错误,err参数会包含错误信息,在回调函数中可以进行错误处理;如果读取成功,文件内容会存储在data参数中并打印出来。

fs.readFileSync():这是fs.readFile()的同步版本。它会阻塞 Node.js 进程,直到文件读取完成。例如:

const fs = require('fs');
const file_path = 'example.txt';
try {
  const data = fs.readFileSync(file_path, 'utf8');
  console.log('文件内容:', data);
} catch (err) {
  console.error('读取文件出错:', err);
}

这里使用try - catch块来捕获可能出现的错误。由于是同步操作,代码的执行顺序比较直观,在读取大文件时可能会导致程序暂时无响应,因为它会等待文件读取完成。

2. 写入文件

fs.writeFile():用于异步地将数据写入文件。如果文件不存在,会创建一个新文件;如果文件已存在,则会覆盖原有内容。例如:

const fs = require('fs');
const file_path = 'new_example.txt';
const data = '这是要写入文件的内容';
fs.writeFile(file_path, data, 'utf8', (err) => {
  if (err) {
    console.error('写入文件出错:', err);
  } else {
    console.log('文件已成功写入');
  }
});

这个例子中,将字符串datautf8编码写入到new_example.txt文件中。同样,通过回调函数处理写入过程中的错误或成功情况。(内容会被覆盖)

fs.writeFileSync():这是fs.writeFile()的同步版本,会阻塞进程直到写入操作完成。例如:

const fs = require('fs');
const file_path = 'new_example.txt';
const data = '这是要写入文件的内容';
try {
  fs.writeFileSync(file_path, data, 'utf8');
  console.log('文件已成功写入');
} catch (err) {
  console.error('写入文件出错:', err);
}

3. 追加文件内容

fs.appendFile():异步地将数据追加到文件末尾(这个解决了**fs.writeFile()**会覆盖前面内容的特点)。例如:

const fs = require('fs');
const file_path = 'append_example.txt';
const data = '这是要追加的内容';
fs.appendFile(file_path, data, 'utf8', (err) => {
  if (err) {
    console.error('追加文件内容出错:', err);
  } else {
    console.log('内容已成功追加到文件');
  }
});
  • fs.writeFile()不同的是,fs.appendFile()不会覆盖原有文件内容,而是在文件末尾添加新内容。
  • **fs.appendFileSync()**:这是fs.appendFile()的同步版本,会阻塞进程进行追加操作。

4. 读取目录内容

fs.readdir():异步地读取目录中的文件和子目录列表。例如:

const fs = require('fs');
const dir_path = 'example_directory';
fs.readdir(dir_path, (err, files) => {
  if (err) {
    console.error('读取目录出错:', err);
  } else {
    console.log('目录中的文件和子目录:', files);
  }
});
  • 这个方法返回目录中的文件名和子目录名的数组。如果需要进一步了解每个文件或子目录的详细信息,可以结合其他方法,如fs.stat()来获取文件或目录的状态信息。
  • fs.readdirSync():这是fs.readdir()的同步版本,会返回目录中的文件和子目录名的数组。

5. 检查文件或目录是否存在

fs.existsSync():这是一个同步方法,用于检查指定的文件或目录是否存在。例如:

const fs = require('fs');
const file_path = 'example.txt';
if (fs.existsSync(file_path)) {
  console.log('文件存在');
} else {
  console.log('文件不存在');
}

需要注意的是,在 Node.js 官方文档中,fs.exists()(异步版本)已被废弃,推荐使用fs.existsSync()(同步版本)或者其他替代方法,如fs.stat()fs.access()来检查文件或目录的存在性。

6. 获取文件或目录的状态信息

fs.stat():异步地获取文件或目录的状态信息,包括文件大小、创建时间、修改时间、权限等。例如:

const fs = require('fs');

const fileOrDirectoryPath = 'example.txt';

fs.stat(fileOrDirectoryPath, (err, stats) => {
    if (err) {
        console.error('获取文件或目录状态出错:', err);
    } else {
        // 检查是文件还是目录
        if (stats.isFile()) {
            console.log('这是一个文件。');
            console.log('文件大小为:', stats.size, '字节');
            console.log('文件的创建时间为:', stats.birthtime);
            console.log('文件的最后访问时间为:', stats.atime);
            console.log('文件的最后修改时间为:', stats.mtime);
        } else if (stats.isDirectory()) {
            console.log('这是一个目录。');
            console.log('目录中的文件数量(大致):', stats.nlink);
        }
    }
});

这里的stats对象包含了许多关于文件或目录状态的属性,可以根据需要获取相应的信息。fs.statSync()是其同步版本。

7. 文件流(Stream)相关操作(高级用法)

fs.createReadStream()fs.createWriteStream():这两个方法用于创建文件读取流和文件写入流,通过流的方式处理文件可以更高效地处理大型文件,避免一次性将整个文件内容加载到内存中。例如,复制一个文件:

const fs = require('fs');
const read_stream = fs.createReadStream('source_file.txt');
const write_stream = fs.createWriteStream('destination_file.txt');
read_stream.on('data', (chunk) => {
  write_stream.write(chunk);
});
read_stream.on('end', () => {
  write_stream.end();
  console.log('文件复制完成');
});

在这个例子中,fs.createReadStream('source_file.txt')创建了一个读取source_file.txt文件的读取流,fs.createWriteStream('destination_file.txt')创建了一个写入destination_file.txt的写入流。当读取流有数据(read_stream.on('data',...))时,将数据块chunk写入到写入流中。当读取流结束(read_stream.on('end',...))时,结束写入流操作,表示文件复制完成。这种方式在处理大型文件时,能够有效地利用内存,提高文件处理的效率。

前面我们写的那个简单的爬虫例子也是用到了fs.createWriteStream(),将爬虫爬到的图片下载到相应的目录下。

;