抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文主要学习了Node处理文件和目录的相关接口,包括读取、写入、复制,以及移动和重命名。

环境

Windows 10 企业版 LTSC 21H2
Node 18.14.0
NPM 9.3.1
NVM 1.1.12

1 概念

文件系统是计算机用于管理数据的一种系统,负责在存储设备上进行文件的存储、检索和更新操作。

2 使用

Node中内置了fs模块,可以对计算机中的数据进行操作。

2.1 文件写入

2.1.1 异步写入

主线程不会等待异步线程,执行效率高。

语法:

js
1
fs.writeFile(file, data[, options], callback)

参数:

  • file:文件名。
  • data:待写入的数据。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
const fs = require('fs');
fs.writeFile('./info.txt', '异步写入数据', err => {
// 写入失败传入错误对象,写入成功传入null
if (err) {
console.error('异步写入失败: ' + err);
return;
}
console.log('异步写入成功');
});
console.log('主方法执行结束');

可以在选项中使用flag标志:

标志 说明 是否创建文件
r 此标志打开文件进行读取
r+ 此标志打开文件进行读写
w+ 此标志打开文件进行读写,并将流定位在文件开头
a+ 此标志打开文件进行读写,并将流定位在文件末尾

示例:

js
1
2
3
4
5
6
7
8
9
10
const fs = require('fs');
fs.writeFile('./info.txt', '异步写入数据', { flag:'a+' }, err => {
// 写入失败传入错误对象,写入成功传入null
if (err) {
console.error('异步写入失败: ' + err);
return;
}
console.log('异步写入成功');
});
console.log('主方法执行结束');

2.1.2 同步写入

主线程等待同步线程,程序执行过程易于理解。

语法:

js
1
fs.writeFileSync(file, data[, options])

参数与writeFile()方法一致,只是没有callback参数。

示例:

js
1
2
3
4
const fs = require('fs');
fs.writeFileSync('./info.txt', '同步写入数据');
console.log('同步写入成功');
console.log('主方法执行结束');

2.1.3 异步追加写入

语法:

js
1
fs.appendFile(path, data[, options], callback)

参数:

  • path:文件路径。
  • data:待写入的数据。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
const fs = require('fs');
fs.appendFile('./info.txt', '异步追加写入数据', err => {
if (err) {
console.error('异步追加写入失败: ' + err);
return;
}
console.log('异步追加写入成功');
});
console.log('主方法执行结束');

2.1.4 同步追加写入

语法:

js
1
fs.appendFileSync(path, data[, options])

参数:与appendFile()方法一致,只是没有callback参数。

示例:

js
1
2
3
4
const fs = require('fs');
fs.appendFileSync('./info.txt', '同步追加写入数据');
console.log('同步追加写入成功');
console.log('主方法执行结束');

2.1.5 流式写入

程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数,适用于大文件写入或者频繁写入的场景。

语法:

js
1
fs.createWriteStream(path[, options])

返回:

  • Object对象,封装了文件流。

参数:

  • path:文件路径。
  • options:选项,可选。

示例:

js
1
2
3
4
5
6
7
const fs = require('fs');
let ws = fs.createWriteStream('./info.txt');
ws.write('123');
ws.write('456');
ws.end();
console.log('流式写入成功');
console.log('主方法执行结束');

2.2 文件读取

2.2.1 异步读取

语法:

js
1
fs.readFile(path[, options], callback)

参数:

  • path:文件路径。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
const fs = require('fs');
fs.readFile('./info.txt', (err, data) => {
if (err) {
console.error('异步读取失败: ' + err);
return;
}
console.log('异步读取成功');
console.log(data.toString());
});
console.log('主方法执行结束');

2.2.2 同步读取

语法:

js
1
fs.readFileSync(path[, options])

返回:

  • Buffer对象,封装了文件内容。

参数:与readFile()方法一致,只是没有callback参数。

示例:

js
1
2
3
4
5
const fs = require('fs');
let data = fs.readFileSync('./info.txt');
console.log('同步读取成功');
console.log(data.toString());
console.log('主方法执行结束');

2.2.3 流式读取

流式读取可以减少打开关闭文件的次数,适用于大文件读取或者频繁读取的场景。

语法:

js
1
fs.createReadStream(path[, options])

返回:

  • Object对象,封装了文件流。

参数:

  • path:文件路径。
  • options:选项,可选。

示例:

js
1
2
3
4
5
6
7
8
9
const fs = require('fs');
let rs = fs.createReadStream('./info.txt');
rs.on('data', trunk => {
console.log(trunk.toString());
});
rs.on('end', () => {
console.log('流式读取成功');
})
console.log('主方法执行结束');

2.3 文件复制

示例:

js
1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
let rs = fs.createReadStream('./img.jpg');
let ws = fs.createWriteStream('./img_back.jpg');
rs.on('data', trunk => {
ws.write(trunk);
});
rs.on('end', () => {
ws.end();
console.log('流式复制成功');
})
console.log('主方法执行结束');

也可以使用pipe()方法进行复制:

js
1
2
3
4
5
const fs = require('fs');
let rs = fs.createReadStream('./img.jpg');
let ws = fs.createWriteStream('./img_back.jpg');
rs.pipe(ws);
console.log('主方法执行结束');

2.4 文件重命名和移动

文件重命名和移动可以用同一个方法实现,也有异步和同步两种方式,同步方法比异步方法少了callback参数。

语法:

js
1
2
fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)

参数:

  • oldPath:原文件路径。
  • newPath:新文件路径。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
fs.rename('./info.txt', './info_new.txt', (err) => {
if (err) {
console.error('异步重命名失败: ' + err);
return;
}
console.log('异步重命名成功');
});
// fs.renameSync('./info.txt', './info_new.txt');
// console.log('同步重命名成功');
console.log('主方法执行结束');

2.5 文件删除

文件删除也有异步和同步两种方式,同步方法比异步方法少了callback参数。

语法:

js
1
2
fs.unlink(path, callback)
fs.unlinkSync(path)

参数:

  • path:文件路径。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
fs.unlink('./info.txt', (err) => {
if (err) {
console.error('异步删除失败: ' + err);
return;
}
console.log('异步删除成功');
});
// fs.unlinkSync('./info.txt');
// console.log('同步删除成功');
console.log('主方法执行结束');

从14.14.0版本开始,还可以使用rm()rmSync()方法实现。

语法:

js
1
2
fs.rm(path[, options], callback)
fs.rmSync(path[, options])

参数:

  • path:文件路径。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
fs.rm('./info.txt', (err) => {
if (err) {
console.error('异步删除失败: ' + err);
return;
}
console.log('异步删除成功');
});
// fs.rmSync('./info.txt');
// console.log('同步删除成功');
console.log('主方法执行结束');

2.6 目录管理

2.6.1 创建目录

语法:

js
1
2
fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])

参数:

  • path:文件路径。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
fs.mkdir('./info', (err) => {
if (err) {
console.error('异步创建目录失败: ' + err);
return;
}
console.log('异步创建目录成功');
});
// fs.mkdirSync('./info');
// console.log('同步创建目录成功');
console.log('主方法执行结束');

支持递归创建目录:

js
1
2
3
4
5
6
7
8
9
const fs = require('fs');
fs.mkdir('./info/1/2/3', { recursive:true }, (err) => {
if (err) {
console.error('递归创建目录失败: ' + err);
return;
}
console.log('递归创建目录成功');
});
console.log('主方法执行结束');

2.6.2 读取目录

语法:

js
1
2
fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])

参数:

  • path:文件路径。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
12
13
const fs = require('fs');
fs.readdir('./info', (err, data) => {
if (err) {
console.error('异步读取目录失败: ' + err);
return;
}
console.log('异步读取目录成功');
console.log(data);
});
// let data = fs.readdirSync('./info');
// console.log('同步读取目录成功');
// console.log(data);
console.log('主方法执行结束');

2.6.3 删除目录

语法:

js
1
2
fs.rmdir(path[, options], callback)
fs.rmdirSync(path[, options])

参数:

  • path:文件路径。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
fs.rmdir('./info', (err) => {
if (err) {
console.error('异步删除目录失败: ' + err);
return;
}
console.log('异步删除目录成功');
});
// fs.rmdirSync('./info');
// console.log('同步删除目录成功');
console.log('主方法执行结束');

支持递归删除目录:

js
1
2
3
4
5
6
7
8
9
const fs = require('fs');
fs.rmdir('./info', { recursive:true }, (err) => {
if (err) {
console.error('递归删除目录失败: ' + err);
return;
}
console.log('递归删除目录成功');
});
console.log('主方法执行结束');

由于该方法已经被标记为过期了,建议使用rm()rmSync()方法实现。

2.7 查看资源状态

语法:

js
1
2
fs.stat(path[, options], callback)
fs.statSync(path[, options])

参数:

  • path:文件路径。
  • options:选项,可选。
  • callback:回调方法。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
12
13
const fs = require('fs');
fs.stat('./info.txt', (err, data) => {
if (err) {
console.error('异步查看资源状态失败: ' + err);
return;
}
console.log('异步查看资源状态成功');
console.log(data);
});
// let data = fs.statSync('./info.txt');
// console.log('同步查看资源状态成功');
// console.log(data);
console.log('主方法执行结束');

判断资源类型:

  • 使用isFile()命令判断资源是否文件。
  • 使用isDirectory()命令判断资源是否目录。

示例:

js
1
2
3
4
5
6
7
8
9
10
11
12
const fs = require('fs');
fs.stat('./info.txt', (err, data) => {
if (err) {
console.error('异步查看资源状态失败: ' + err);
return;
}
console.log('异步查看资源状态成功');
console.log(data);
console.log('判断资源是否文件: ' + data.isFile());
console.log('判断资源是否目录: ' + data.isDirectory());
});
console.log('主方法执行结束');

评论