学习视频:尚硅谷2023版Node.js零基础视频教程,nodejs新手到高手
- fs:
file system
,文件系统。- fs模块可以实现与硬盘的交互,例如文件的创建、删除、重命名、移动、内容的写入读取以及文件夹的相关操作。
语法:fs.writeFile(file,data[,options],callback)
参数说明:
file
文件名data
待写入的数据options
选项设置(可选)callback
写入回调返回值:undefined
/**
* 需求:
* 新建一个文件, 座右铭.txt, 写入内容, 三人行, 则必有我师焉
*/
//1. 导入 fs 模块
const fs = require('fs');
//2. 写入文件
fs.writeFile('./座右铭.txt', '三人行, 则必有我师焉', err =>
{
// err(回调函数)写入失败: 错误对象 写入成功: null
if(err){
console.log('写入失败');
return;
}
console.log('写入成功');
});
异步
:如下,1+1在最后,但它压根不带等上边的,它俩一块运行,谁也不妨碍谁,1+1先跑完就先输出。
/**
* 需求:
* 新建一个文件, 座右铭.txt, 写入内容, 三人行, 则必有我师焉
*/
//1. 导入 fs 模块
const fs = require('fs');
//2. 写入文件
fs.writeFile('./座右铭.txt', '三人行, 则必有我师焉', err =>
{
// err(回调函数)写入失败: 错误对象 写入成功: null
if(err){
console.log('写入失败');
return;
}
console.log('写入成功');
});
console.log(1 + 1);
语法: fs.writeFileSync(file, data[, options])
参数与 fs.writeFile 大体一致,只是没有 callback 参数。
返回值: undefined
//1. 导入 fs 模块
const fs = require('fs');
//2. 写入文件
//同步写入
fs.writeFileSync('./data.txt', 'test');
console.log(1 + 1);
同步
:就是一条道,我走完你再走,从上到下顺序执行。
/**
* 需求:
* 新建一个文件, 座右铭.txt, 写入内容, 三人行, 则必有我师焉
*/
//1. 导入 fs 模块
const fs = require('fs');
//2. 写入文件
//同步写入
try{
fs.writeFileSync('./座右铭.txt', '三人行,必有我师焉。');
console.log('OK');
}
catch(e){
console.log(e);
}
console.log(1 + 1);
Node.js 中的磁盘操作是由其他线程完成的,结果的处理有两种模式:
同步处理
:JavaScript主线程会等待其他线程的执行结果,然后再继续执行主线程的代码,效率较低。异步处理
:JavaScript主线程不会等待其他线程的执行结果,直接执行后续的主线程代码,效率较好。appendFile 作用是在文件尾部追加内容,appendFile 语法与 writeFile 语法完全相同。
语法:
fs.appendFile(file, data[, options], callback)
fs.appendFileSync(file, data[, options])
返回值: 二者都为 undefined
//1. 引入 fs 模块
const fs = require('fs');
//2. 调用 appendFile
fs.appendFile('./座右铭.txt', ',择其善者而从之, 择期不善者而改之', err => {
//判断
if(err){
console.log('写入失败~~');
return;
}
console.log('追加写入成功');
});
fs.appendFileSync('./座右铭.txt', '\r\n温故而知新, 可以为师矣')
//writeFile 实现追加写入
fs.writeFile('./座右铭.txt', 'love love love',{flag: 'a'}, err => {
if(err) {
console.log('写入失败~');
return ;
}
console.log('写入成功');
});
fs.createWriteStream(path[, options])
path
:文件路径options
:选项配置( 可选 )Object
//1. 导入 fs
const fs = require('fs');
//2. 创建写入流对象
const ws = fs.createWriteStream('./观书有感.txt');
//3. write
ws.write('半亩方塘一鉴开\r\n');
ws.write('天光云影共徘徊\r\n');
ws.write('问渠那得清如许\r\n');
ws.write('为有源头活水来\r\n');
//4. 关闭通道
ws.close();
语法: fs.readFile(path[, options], callback)
参数说明:
path
:文件路径options
:选项配置callback
:回调函数返回值: undefined
//1. 引入 fs 模块
const fs = require('fs');
//2. 异步读取
fs.readFile('./观书有感.txt', (err, data) => {
if(err) {
console.log('读取失败~~');
return;
}
console.log(data.toString());
});
语法: fs.readFileSync(path[, options])
参数说明:
path
:文件路径options
:选项配置返回值:string | Buffer
//1. 引入 fs 模块
const fs = require('fs');
//2. 同步读取
let data = fs.readFileSync('./观书有感.txt');
console.log(data.toString());
语法: fs.createReadStream(path[, options])
参数说明:
path
:文件路径options
:选项配置( 可选 )返回值: Object
//1. 引入 fs 模块
const fs = require('fs');
//2. 创建读取流对象
const rs = fs.createReadStream('../资料/笑看风云.mp4');
//3. 绑定 data 事件 chunk 块儿 大块儿
rs.on('data', chunk => {
console.log(chunk.length); // 65536 字节 => 64KB,每次读取64KB的数据
});
//4. end 可选事件
rs.on('end', () => {
console.log('读取完成');
});
/**
* 需求:
* 复制『资料』文件夹下的『笑看风云.mp4』
*/
const fs = require('fs');
//方式一 readFile
//读取文件内容
let data = fs.readFileSync('../资料/笑看风云.mp4');
//写入文件
fs.writeFileSync('../资料/笑看风云-2.mp4', data);
//方式二 流式操作
//创建读取流对象
const rs = fs.createReadStream('../资料/笑看风云.mp4');
//创建写入流对象
const ws = fs.createWriteStream('../资料/笑看风云-3.mp4');
//绑定 data 事件
rs.on('data', chunk => {
ws.write(chunk);
});
查看内存占用量
const fs = require('fs');
const process = require('process');
//方式一 readFile
let data = fs.readFileSync('../资料/笑看风云.mp4');
fs.writeFileSync('../资料/笑看风云-2.mp4', data);
console.log("我是readfile的结果");
console.log(process.memoryUsage());
//方式二 流式操作
const rs = fs.createReadStream('../资料/笑看风云.mp4');
const ws = fs.createWriteStream('../资料/笑看风云-3.mp4');
//绑定 data 事件(2.1)
rs.on('data', chunk => {
ws.write(chunk);
});
rs.on('end', () => {
console.log("我是流式读取的结果");
console.log(process.memoryUsage());
})
//(2.2),借助管道完成读取
// rs.pipe(ws);
视频里头流式处理可厉害了,我这咋流式处理菜菜的?- 流式处理所占用的内存比直接读取更大是因为流式处理需要在处理数据时逐行或逐块读取数据,并将其存储在内存中以进行后续处理。这意味着在读取数据时,需要维护一个缓冲区来存储数据,因此在处理大量数据时,内存的使用率可能比直接读取更高。
- 另外,流式处理还需要在处理后及时释放内存,否则可能会导致内存泄漏和程序崩溃等问题。因此,在设计流式处理程序时需要特别注意内存的使用和释放问题,以确保程序的稳定性和可靠性。
rename
或renameSync
来移动或重命名 文件或文件夹fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
oldPath
:文件当前的路径newPath
:文件新的路径callback
:操作后的回调//1. 导入 fs 模块
const fs = require('fs');
//2. 调用 rename 方法
fs.rename('./座右铭.txt', './论语.txt', err => {
if(err) {
console.log('操作失败~');
return;
}
console.log('操作成功');
});
//文件的移动
fs.rename('./data.txt', '../资料/data.txt', err => {
if(err) {
console.log('操作失败~');
return;
}
console.log('操作成功');
})
unlink
或unlinkSync
或rm
或rmSync
来删除文件。fs.unlink(path, callback)
fs.unlinkSync(path)
fs.rm(path, callback)
fs.rmSync(path)
path
:文件路径callback
:操作后的回调//1. 导入 fs 模块
const fs = require('fs');
//2. (一)调用 unlink 方法 unlinkSync
fs.unlink('./观书有感.txt', err => {
if(err) {
console.log('删除失败~');
return;
}
console.log('删除成功');
});
// 2. (二)调用 rm 方法 rmSync
fs.rm('./论语.txt', err => {
if (err) {
console.log('删除失败~');
return;
}
console.log('删除成功');
})
补充笔记:常用的 Linux 操作
mkdir
或 mkdirSync
来创建文件夹fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])
path
:文件夹路径options
:选项配置( 可选 )callback
:操作后的回调readdir
或 readdirSyn
来创建文件夹fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
path
:文件夹路径options
:选项配置( 可选 )callback
:操作后的回调rmdir
或 rmdirSync
来创建文件夹fs.rmdir(path[, options], callback)
fs.rmdirSync(path[, options])
path
:文件夹路径options
:选项配置( 可选 )callback
:操作后的回调//1. 导入 fs 模块
const fs = require('fs');
//2. 创建文件夹 mk make 制作 dir directory 文件夹
fs.mkdir('./html', err => {
if(err) {
console.log('创建失败~');
return;
}
console.log('创建成功');
});
//2-2 递归创建
fs.mkdir('./a/b/c', {recursive: true},err => {
if(err) {
console.log('创建失败~');
return;
}
console.log('创建成功');
});
//2-3 读取文件夹 read 读取 dir directory 文件夹
fs.readdir('../资料', (err, data) => {
if(err){
console.log('读取失败');
return;
}
console.log(data);
});
fs.readdir('./', (err, data) => {
if(err){
console.log('读取失败');
return;
}
console.log(data);
});
//2-4 删除文件夹 rm remove 移除
fs.rmdir('./html', err => {
if(err){
console.log('删除失败');
return;
}
console.log('删除成功');
});
//递归删除 不推荐使用
// fs.rmdir('./a', {recursive: true},err => {
// if(err){
// console.log(err);
// return;
// }
// console.log('删除成功');
// });
//建议使用
fs.rm('./a', {recursive: true},err => {
if(err){
console.log(err);
return;
}
console.log('删除成功');
});
需求:批量重命名,把1、2等变为01、02等,可应用于防止网盘文件错位。
//导入 fs 模块
const fs = require('fs');
//读取 code 文件夹
const files = fs.readdirSync('./code');
//遍历数组
files.forEach(item => {
//拆分文件名
let data = item.split('-');
let [num, name] = data;//num存数字,name存文件名
//判断
if(Number(num) < 10){
num = '0' + num;
}
//创建新的文件名
let newName = num + '-' + name;
//重命名
fs.renameSync(`./code/${item}`, `./code/${newName}`);
})
需求:批量重命名并排好序,比如1、3、4变为01、02、03。
//导入 fs 模块
const fs = require('fs');
//读取 code 文件夹
const files = fs.readdirSync('./code');
//遍历数组
files.forEach((item, index) => {
//拆分
let [num, name] = item.split('-');
//index 自增
index++;
//判断
index = index < 10 ? '0' + index : index;
//拼接新的名字
let newName = index + '-' + name;
//移动文件
fs.renameSync(`./code/${item}`, `./code/${newName}`);
});
在 Node.js 中,我们可以使用 stat
或 statSync
来创建文件夹
语法:
fs.stat(path[, options], callback)
fs.statSync(path[, options])
参数说明:
path
:文件夹路径options
:选项配置( 可选 )callback
:操作后的回调//1. 导入 fs 模块
const fs = require('fs');
//2. stat 方法 status 缩写 状态
fs.stat('../资料/笑看风云.mp4', (err, data) => {
if(err){
console.log('操作失败');
return;
}
console.log(data);
console.log(data.isFile());
console.log(data.isDirectory());
});
size
文件体积birthtime
创建时间mtime
最后修改时间isFile
检测是否为文件isDirectory
检测是否为文件夹学习html图片标签时对相对路径问题有过介绍