fs模块可以实现与硬盘的交互,例如文件的创建、删除、重命名、移动,还有文件内容的写入、读取,以及文件夹的相关操作。
目录
3.appendFile/appendFileSync 追加写入
一、写入文件
1.writeFile 异步写入
语法:fs.writeFile(file, data[, options], callback)
参数:
- file <String> | <Buffer> | <URL> |<integer> 文件路径
- data <String> | <Buffer> | <TypeArry> | <DataView> 待写入数据
- options <Object> | <String> 可用于指定将影响输出的可选参数。它具有三个可选参数:
- encoding <String> | <null> 用于指定文件的编码。默认值为“ utf8”。
- mode <integer> 指定文件模式。默认值为0o666。
- flag <String> 用于指定写入文件时使用的标志。默认值为“ w”。
- callback <Function> 回调函数
- err <Error>
返回值: undefined
例:在fs下新建fs1.txt文件,写入 1.怀民亦未寝,___________。
//1.导入fs模块
//require是node的全局变量用来导入模块
const fs = require('fs');
//2.写入文件
fs.writeFile('fs/fs1.txt', '1.怀民亦未寝,___________。', err => {
//如果写入失败,就是一个错误对象,写入成功就是null
if (err) {
console.log('error')
return;
}
console.log('success')
})
console.log(1+1);
/*运行结果
2
success
*/
注意:
异步:写入文件交给另一个线程,主线程不会等待结果,所以先执行 console.log(1+1) 。等待I/O线程执行完毕后,把err=>{}回调函数放入队列当中,等JS主线程把初始化代码都执行完毕后,再去任务队列中取出回调函数再执行。
2.writeFileSync 同步写入
与writeFile工作模式不同,I/O线程开始进行磁盘写入,主线程等待结果,等写入完成后,主线程再继续执行。
语法:fs.writeFileSync(file, data, [options])
参数:
- file <String> |<Buffer> | <URL> | <integer>
- data <String> |<Buffer> | <TypeArry> | <DataView>
- options <Object> | <String>
- encoding <String> | <null> 默认值为“ utf8”。
- mode <integer> 默认值为0o666。
- flag <String> 默认值为“ w”。
返回值: undefined
fs.writeFileSync('fs/data.txt','test')
3.appendFile/appendFileSync 追加写入
appendFile作用是再文件尾部追加内容,appendFile语法与writeFile完全相同。
语法:fs.appendFile(path, data[, options], callback)
参数:
- path <String> | <Buffer> | <URL> | <number>
- data <String> | <Buffer>
- options <Object> | <String>
- encoding <String> | <null> 默认值为“ utf8”。
- mode <integer> 默认值为0o666。
- flag <String> 默认值为“ a”。
- callback <Function>
- err <Error>
返回值: undefined
语法:fs.appendFileSync (path, data[, options])
- path <String> |<Buffer> | <URL> | <number>
- data <String> |<Buffer>
- options <Object> | <String>
- encoding <String> | <null> 默认值为“ utf8”。
- mode <integer> 默认值为0o666。
- flag <String> 默认值为“ a”。
返回值: undefined
例:对fs下fs1.txt文件,追加写入 庭下如积水空明,水中藻、荇交横,盖竹柏影也。
const fs = require('fs');
fs.appendFile('fs/fs1.txt','庭下如积水空明,水中藻、荇交横,盖竹柏影也。',err=>{
if (err) {
console.log('error')
return;
}
console.log('success')
});
fs.appendFileSync('fs/fs1.txt','\r\n何夜无月?何处无竹柏?');
fs.writeFile('fs/fs1.txt', '\r\n但少闲人如吾两人者耳。',{flag:'a'}, err => {
if (err) {
console.log('error')
return;
}
console.log('success')
});
注意:
fs.writeFile()以异步的方式将data写入文件,文件已存在的情况下,原内容将被替换。所以要实现追加内容,必须指定配置对象的标识属性flag。
4.createWriteScream 流式写入
语法:fs.createWriteScream (path[, options])
参数:
- path <String> |<Buffer> | <URL> 文件路径
- options <Object> | <String> 选项配置(可选)
- flags <String> 默认值为“ w”。
- encoding <String> 默认值为“ utf8”。
- mode <integer> 默认值为0o666。
- autoClose <boolean> 默认值:true
- emitClose <boolean> 默认值:false
- fd <String> 默认值:null
- fs <Object> | <null> 默认值:null
- start <integer>
返回值: fs.WriteScream
例:对fs下fs2.txt文件,写入 锦瑟无端五十弦,一弦一柱思华年。庄生晓梦迷蝴蝶,望帝春心托杜鹃。
const fs = require('fs');
//创建写入流对象
const ws = fs.createWriteStream('fs/fs2.txt');
//写入内容
ws.write('锦瑟无端五十弦,')
ws.write('一弦一柱思华年。')
ws.write('庄生晓梦迷蝴蝶,')
ws.write('望帝春心托杜鹃。')
//关闭通道
ws.close()
程序打开需要消耗资源,流式写入可减少文件打开次数。流式写入适用于大文件或频繁写入的场景,writleFile适用于写入频率低的场景
总结:
当需要持久化保存数据的时候,应该想到文件写入。一般用于下载文件、安装软件、保存程序日志、编辑器保存文件、视频录制等。
二、文件读取
1.readFile 异步读取
语法:fs.readFile (path[, options], callback)
参数:
- path <String> |<Buffer> | <URL> | <integer>
- options <Object> | <String> 配置项,它具有两个可选参数:
- encoding <String> | <null> 默认值为“ null”
- flag <String> 默认值为“ r”。
- callback <Function>
- err <Error>
- data <String> |<Buffer>
返回值: undefined
注意:如果指定了encoding类型,则此函数返回字符串,否则返回buffer
const fs = require('fs');
//异步读取
fs.readFile('../fs/fs1.txt', (err, data) => {
if (err) {
console.log('error')
return;
}
//buffer转string
console.log(data.toString());
})
/*运行结果
1.怀民亦未寝,___________。庭下如积水空明,水中藻、荇交横,盖竹柏影也。
何夜无月?何处无竹柏?
但少闲人如吾两人者耳。
*/
2.readFileSync 同步读取
语法:fs.readFileSync(path[, options])
参数:
- path <String> |<Buffer> | <URL> | <integer>
- options <Object> | <String> 配置项,它具有两个可选参数:
- encoding <String> | <null> 默认值为“ null”
- flag <String> 默认值为“ r”。
返回值: String | Buffer
//同步读取
let data= fs.readFileSync('../fs/fs1.txt');
console.log(data.toString());
let data2= fs.readFileSync('../fs/fs1.txt',{encoding:'utf-8'});
console.log(data2);
3.createReadStream 流式读取
语法:fs.createReadStream (path[, options])
参数:
- path <String> | <Buffer> | <URL>
- options <Object> | <String> 选项配置(可选)
- flags <String> 默认值为“ r”。
- encoding <String> 默认值为“ null”。
- mode <integer> 默认值为0o666。
- autoClose <boolean> 默认值:true
- emitClose <boolean> 默认值:false
- fd <String> 默认值:null
- fs <Object> | <null> 默认值:null
- start <integer>
- end <integer> 默认值: Infinity
- highWaterMark <integer> 默认值: 64 * 1024
返回值: fs.ReadScream
const fs = require('fs');
const rs = fs.createReadStream('../fs/fs2.txt');
//3.绑定data事件 chunk:块
//每当读完一块,就会执行回调函数,并将读取到的内容传给chunk。每次读取64KB。
rs.on('data', chunk => {
console.log(chunk.toString());
})
//4.end 可选事件
rs.on('end', ()=> {
console.log('读取完成');
})
/*运行结果
锦瑟无端五十弦,一弦一柱思华年。庄生晓梦迷蝴蝶,望帝春心托杜鹃。
读取完成
*/
三、文件操作
1.文件复制
例:复制fs文件夹下的test.heml
const fs = require('fs');
//方法一:readFile
let data= fs.readFileSync('../fs/test.html');
fs.writeFileSync('../fs2/copy.html',data);
//console.log(process.memoryUsage());//rss: 19927040,19460KB
//方式二:流式操作
//创建读取流对象
const rs = fs.createReadStream('../fs/test.html');
//创建写入流对象
const ws1 = fs.createWriteStream('../fs2/copy2.html');
rs.on('data',chunk=>{
ws1.write(chunk)
})
rs.on('end',()=>{
//console.log(process.memoryUsage());//rss: 21774336,21264KB
})
//方式三:pipe 管道
//创建写入流对象
const ws2 = fs.createWriteStream('../fs2/copy3.html');
rs.pipe(ws2);
2.rename/renameSync 重命名或移动
语法:fs.rename(oldPath,newPath,callback)
参数:
- oldPath <String> | <Buffer> | <URL>
- newPath <String> | <Buffer> | <URL>
- callback <Function>
- err <Error>
语法:fs.renameSync(oldPath,newPath)
参数:
- oldPath <String> | <Buffer> | <URL>
- newPath <String> | <Buffer> | <URL>
例:将fs文件夹下的data.txt,重名名为data2.txt,并将其移动到fs2文件夹下
const fs = require('fs');
//调用rename
//重命名
fs.rename('../fs/data.txt', '../fs/data2.txt', err => {
if (err) {
console.log('error')
return;
}
console.log('success')
})
//移动
fs.rename('../fs/data2.txt', '../fs2/data2.txt', err => {
if (err) {
console.log('error')
return;
}
console.log('success')
})
fs.renameSync('../fs/test.html','../fs/index.html')
3.unlink/unlinkSync 文件删除
语法:fs.unlink(path,callback)
参数:
- path <String> | <Buffer> | <URL>
- callback <Function>
- err <Error>
语法:fs.unlinkSync(path)
参数:
- path<String> | <Buffer> | <URL>
例.删除fs文件夹下的delete.css和delete2.css文件
const fs = require('fs');
fs.unlink('../fs/delete.css', err => {
if (err) {
console.log('error')
return;
}
console.log('success')
})
fs.unlinkSync('../fs/delete2.css')
//rm/rmSync node.14.4
/*
fs.rm('../fs/test.txt', err => {
if (err) {
console.log('error')
return;
}
console.log('success')
})
*/
四、文件夹操作
1.mkdir 创建
语法:fs.mkdir(path[,options],callback)
参数:
- path <String> | <Buffer> | <URL>
- options <Object> | <integer> 它具有两个可选参数:
- mode <integer> 默认值为0o777。
- recursive <boolean> 递归创建。默认值:false
- callback <Function>
- err <Error>
const fs = require('fs');
fs.mkdir('./floader',err=>{
if (err) {
console.log('error')
return;
}
console.log('success')
})
//递归创建
fs.mkdir('./floader/a/b/c',{recursive:true},err=>{
if (err) {
console.log('error')
return;
}
console.log('success')
})
2.readdir/readdirSync 读取
语法:fs.readdir(path[,options],callback)
参数:
- path <String> | <Buffer> | <URL>
- options <Object> | <integer> 它具有两个可选参数:
- encoding <String> 默认值为“ utf8”。
- withFileTypes <boolean> 如果 options.withFileTypes 被设置为 true,则 files 数组会包含 fs.Dirent 对象。默认值:false
- callback <Function>
- err <Error>
- files <String[ ]> | <Buffer[ ]> | <fs.Dirent[ ]>
语法:fs.readdirSync(path[,options])
参数:
- path <String> | <Buffer> | <URL>
- options <Object> | <integer> 它具有两个可选参数:
- encoding <String> 默认值为“ utf8”。
- withFileTypes <boolean> 如果 options.withFileTypes 被设置为 true,则 files 数组会包含 fs.Dirent 对象。默认值:false
返回值:<String[ ]> | <Buffer[ ]> | <fs.Dirent[ ]>
const fs = require('fs');
//读取当前文件夹
fs.readdir('./',(err,data)=>{
if (err) {
console.log('error')
return;
}
console.log(data);//[ '1.文件夹创建.js', '2.读取文件夹.js', 'floader' ]
})
let file = fs.readdirSync('./',{withFileTypes:true});
console.log(file)
/*运行结果
[
Dirent { name: '1.文件夹创建.js', [Symbol(type)]: 1 },
Dirent { name: '2.读取文件夹.js', [Symbol(type)]: 1 },
Dirent { name: 'floader', [Symbol(type)]: 2 }
]
*/
3. rmdir 删除
语法:fs.rmdir(path[,options],callback)
参数:
- path <String> | <Buffer> | <URL>
- options <Object> 它具有三个可选参数:
- recursive <boolean> 递归。默认值:false
- maxRetries <integer> 默认值:false
- retryDelay <integer> 默认值:100
- callback <Function>
- err <Error>
语法:fs.rmdirSync(path[,options])
参数:
- path <String> | <Buffer> | <URL>
- options <Object> 它具有三个可选参数:
- recursive <boolean> 递归。默认值:false
- maxRetries <integer> 默认值:false
- retryDelay <integer> 默认值:100
//删除文件夹
fs.rmdir('./floader/a/b/c',err=>{
if (err) {
console.log('error')
return;
}
console.log('success')
})
//删除非空文件夹,需要使用递归删除
fs.rmdirSync('./floader/a',{recursive:true})
五、查看资源状态
语法:fs.stat(path[,options],callback)
参数:
- path <String> | <Buffer> | <URL>
- options <Object> 它具有一个可选参数:
- bigint <boolean> 默认值:false
- callback <Function>
- err <Error>
- stats <fs.Stats>
语法:fs.statSync(path[,options])
const fs = require('fs');
fs.stat('../4.文件夹操作/floader/test.css',(err,data)=>{
if (err) {
console.log('error')
return;
}
//console.log(data)
console.log(data.isFile());//true
console.log(data.isDirectory());//false
})
Stats {
dev: 1317745789,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 1688849860651598,
size: 103,//文件大小
blocks: 0,
atimeMs: 1681464807760.8076,
mtimeMs: 1681464807760.8076,
ctimeMs: 1681464807760.8076,
birthtimeMs: 1681464771314.5503,
atime: 2023-04-14T09:33:27.761Z,//最后访问时间
mtime: 2023-04-14T09:33:27.761Z,//最后修改时间
ctime: 2023-04-14T09:33:27.761Z,//最后修改文件状态的时间
birthtime: 2023-04-14T09:32:51.315Z//文件创建时间
}
六、路径
1.文件路径
以 2.读取文件夹.js 为基础
相对路径 | 绝对路径 | |
当前目录下的1.文件夹创建.js文件 ./1.文件夹创建.js =1.文件夹创建.js | D:/..../4.文件夹操作/1.文件夹创建.js | |
当前目录的上一级目录的fs下的fs1.txt ../fs/fs1.txt |
绝对路径:所在文件所在目录的绝对路径
console.log(__dirname);
// D:\...\...\...\2.fs模块\4.文件夹操作
2.网页中的URL
网页中的URL主要分为:相对路径和绝对路径
- 绝对路径
形式 | 特点 |
---|---|
https://cn.vitejs.dev/guide/features.html | 直接向目标资源发送请求。网站外链。 |
//jd.com | 与页面的URL协议形成完整的URL再发送请求 |
/search | 与页面URL、主机名、端口拼接成完整的URL再发送请求 |
- 相对路径:相对路径发送请求,需要与当前URL路径进行计算,得到完整的URL后,再发送请求
形式 | 最终的URL |
---|---|
./css/index.css | http://127.0.0.1:5000/css/index.css |
../js/index.js | http://127.0.0.1:5000/js/index.js |
七、批量重命名
const fs = require('fs');
//读取文件夹
const files = fs.readdirSync('./')
console.log(files);//[ '1_stat.js', '2_批量重命名.js' ]
//遍历数组
files.forEach(item=>{
//拆分文件名
let data = item.split('_');
let [code,name] = data;
// console.log(code,name);
/*运行结果
01-stat.js
02-批量重命名.js
*/
//判断
if(Number(code) < 10){
code = '0'+code;
}
let newname = code+"-"+name;
//console.log(newname)
//重命名
fs.renameSync(`./${item}`,`./${newname}`);
})