fs(file system 的缩写,译为“文件系统”)
fs 模块可以实现与硬盘的交互,例如:文件按的创建、删除、重命名、移动,还有文件内容的写入、读取,以及文件夹的相关操作
/**
* 需求:
* 新建一个文件,test.txt, 写入内容:hello world
*/
// 1. 导入 fs 模块
const fs = require('fs')
// 2.写入文件
fs.writeFile('./test.txt','hello world', err =>{
// 写入完成后调用
//err 写入失败:错误对象 写入成功:null
if(err){
console.log('写入失败');
return
}
console.log('写入成功')
})
I/O:输入输出
异步写入:writeFile
同步写入:writeFileSync
异步操作效率更高,同步api更容易理解
appendFile:异步追加
appendFileSync:同步追加
fs.appendFile('./test_3.text','test111',(error) => {
if(error){
console.log('写入失败~~~')
return
}
console.log('写入成功')
})
fs.appendFileSync('./test_4.text','\r\ntest111')
writeFile也可以实现追加,需要在第三个配置对象中设置flag:'a'
fs.writeFile('./test_4.text','test2222', {
flag:'a'
}, (error) => { })
createWriteStream 流式写入,相比writeFile,更适合写入频率较高的场合
或者大文件的写入
程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数
流式写入方式适用于大文件写入或者频繁写入
的场景,writeFile
适合于写入频率较低
的场景
// 1. 导入fs
const fs = require('fs')
// 2. 创建写入流对象
const ws = fs.createWriteStream('./streamText.txt')
// 3. write
ws.write('test1\r\n')
ws.write('test2\r\n')
ws.write('test3\r\n')
ws.write('test4\r\n')
// 4. 关闭通道
ws.close()
git add -A 存档,存储到object文件夹下
当
需要持久保存数据
的时候,应该想到文件写入
readFile 异步读取
readFileSync 同步读取
// 1. 引入 fs 模块
const fs = require('fs')
// 2. 异步读取
fs.readFile('./streamText.txt', (err, data) => {
if (err) {
console.log('err :>> ', err);
return
}
console.log('data :>> ', data.toString());
})
// 3. 同步读取
const dataSync = fs.readFileSync('./streamText.txt')
console.log('dataSync :>> ', dataSync.toString());
// dataSync :>>
// test1
// test2
// test3
// test4
// data :>>
// test1
// test2
// test3
// test4
createReadStream:会将文件分块读取,每一块为 64kb
// 1. 引入 fs 模块
const fs = require('fs')
// 2. 创建读取流对象
const rs = fs.createReadStream('../myFiles/guidao1.copy.jpg')
// 3. 绑定 data 事件 chunk:块儿 大块儿
rs.on('data', chunk =>{
console.log('chunk.length :>> ', chunk.length); // 65536 => 64kb
})
// 4. end 可选事件
rs.on('end', ()=>{
console.log('读取完成')
})
/**
* 需求:复制一个文件
*/
const fs = require('fs')
const process = require('process')
// 方法一:readFile
const data = fs.readFileSync('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会.mp4')
// 写入文件
fs.writeFileSync('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会2.mp4',data)
console.log('process.memoryUsage() :>> ', process.memoryUsage());
// 518475776 字节=> 494.45703125 MB
// 方式二:流式操作
// 创建读取流对象
const rs = fs.createReadStream('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会.mp4')
// 创建写入流对象
const ws = fs.createWriteStream('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会3.mp4')
// 绑定 data 事件
rs.on('data', chunk=>{
ws.write(chunk)
})
rs.on('end', ()=>{
console.log('process.memoryUsage() :>> ', process.memoryUsage());
//54386688 字节=> 51.8671875 MB
})
// pipe: 中文译为管道
// 将读取流直接交给写入流,简写,使用并不多
// rs.pipe(ws)
readFile 是直接将文件读取写入内存,流式操作则会分块读取
理想状态上流式操作只需要 64kb 的内存,要比 readFile 一次性读取文件节省内存
但是实际上,由于读取速度比写入速度要快,所以流式操作需要更多的内存
实测,在文件并不大的情况下,流式操作占据内存更多,但如果是大文件,流式内存更节省内存
rename: 异步方式,重命名文件名,也可以移动文件,但是**如果文件夹不存在,会移动失败**
renameSync: 同步方式
const fs = require('fs')
fs.rename('../资料/视频.mp4', '../资料/test_视频.mp4', (err) => {
if (err) {
console.log('err :>> ', err);
return
}
console.log('重命名成功')
})
fs.renameSync('../资料/test_视频.mp4', '../资料/视频.mp4')
unlink
unlinkSync
rm
rmSync
const fs = require('fs')
fs.unlink('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会3.mp4', err=>{
if(err){
console.log('err :>> ', err);
return
}
console.log('删除成功')
})
const unlinkSync = fs.unlinkSync('../myFiles/text2.txt')
console.log('unlinkSync :>> ', unlinkSync);
fs.rm('../myFiles/【渐构】万字科普ChatGPT-4为什么会颠覆人类社会4.mp4',err=>{
if(err){
console.log('err :>> ', err);
return
}
console.log('删除成功')
})
const rmSync = fs.rmSync('../myFiles/text.txt')
console.log('rmSync :>> ', rmSync);
在vscode的设置中搜索compact,可以设置取消以紧凑形式显示文件夹
mk=> make 制作
dir => directory 文件夹
const fs = require('fs')
fs.mkdir('../makedir/a/b/c', { recursive: true}, err=>{
if(err){
console.log('err :>> ', err);
return
}
console.log('创建成功')
})
const mkdirSync = fs.mkdirSync('../makedir/b/c/d', { recursive: true})
console.log('mkdirSync :>> ', mkdirSync);
const fs = require('fs')
fs.readdir('../myFiles',(err, dirName)=>{
if (err) {
console.log('err :>> ', err);
return
}
console.log('dirName :>> ', dirName);
})
const dirNameArry = fs.readdirSync('../myFiles')
console.log('dirNameArry :>> ', dirNameArry);
const fs = require('fs')
fs.rmdir('../makedir/a',{ recursive: true}, err=>{
if(err){
console.log('err :>> ', err);
return
}
console.log('移除成功')
})
fs.rm('../makedir',{ recursive: true}, err=>{
if(err){
console.log('err :>> ', err);
return
}
console.log('移除成功')
})
const fs = require('fs');
fs.stat('../myFiles',(err, data) => {
if(err){
console.log('err :>> ', err);
return
}
console.log('data :>> ', data);
console.log('data.isFile() :>> ', data.isFile());
console.log('data.isDirectory() :>> ', data.isDirectory());
})
相对路径
const fs = require('fs');
fs.writeFileSync('./testIndex.html','test')
fs.writeFileSync('testIndex.html','test')
fs.writeFileSync('../testIndex.html','test')
绝对路径
const fs = require('fs');
fs.writeFileSync('D:/testIndex.html','test')
fs.writeFileSync('/testIndex.html','test')
相对路径的参照物:命令行的工作目录
所以相对路径并不稳定
__dirname 保存的是:所在文件的所在目录的绝对路径
const fs = require('fs');
// fs.writeFileSync('testIndex.html','test')
fs.writeFileSync(__dirname + '/testIndex.html','test') // 这种路径拼接写法并不规范,最好使用 path.resolve 包裹一下
//fs.writeFileSync(path.resolve(__dirname + 'testIndex.html','test'))