node 文件系统总结和封装深度删除rm和复制copy
删除空目录,不是空目录会报错(同步) :fs.rmdirSync(path[, options])
fs.rmdirSync("./test/test1")
删除文件(同步):fs.unlinkSync(path)
fs.unlinkSync("./1.js")
检测文件或者目录路径是否存在,没有检测读写权限是否存在(同步):fs.existsSync(path)
fs.existsSync("./test/test1/1.js")
检测文件或者目录是否存在,读写权限mode(同步):fs.accessSync(path[, mode])
mode为常量 取值有:
fs.constants.F_OK:文件是否存在
fs.constants.W_OK:文件是否可写
fs.constants.R_OK:文件是否可读
fs.accessSync("./img",fs.constants.R_OK | fs.constants.W_OK)
检测路径对应是否是目录,返回布尔值(同步):stats.isDirectory()
fs.statSync("./test").isDirectory()
检测路径对应是否是文件,返回布尔值(同步):stats.isFile()
fs.statSync("./1.txt").isFile()
读取目录,如果路径不存在会报错(同步):fs.readdirSync(path[, options])
fs.readdirSync("./test")
读取文件,默认返回的是buffer,可以指定:utf-8(同步):fs.readFileSync(path[, options])
fs.readFileSync("./1.js",'utf8')
写入文件,覆盖原来的,文件不存在自动创建,目录必须先存在(同步):fs.writeFileSync(file, data[, options])
fs.writeFileSync("./1.txt","this is write data\n")
向文件中追加内容,文件不存在自动创建,目录必须先存在(同步):fs.appendFileSync(path, data[, options])
fs.appendFileSync('./.txt', 'this is append data\n', 'utf8');
重命名或者移动文件/目录,文件/目录不存在会报错(同步):fs.renameSync(oldPath, newPath)
//重命名目录,test1目录改为test2 fs.renameSync("./test1","./test2"); //移动目录,将test1目录 移动在test目录(必须存在)下,目录名不变为test1 fs.renameSync("./test1","./test/test1"); //移动且重命名目录,将test1目录 移动在test目录(必须存在)下,原目录名test1重名为test2 fs.renameSync("./test1","./test/test2"); //重命名文件 1.txt 改为2.txt fs.renameSync("./1.txt","./2.txt") //移动文件,将1.txt 移动在test目录(必须存在)下,文件名不变为1.txt fs.renameSync("./1.txt","./test/1.txt"); //移动且重命名文件,将1.txt文件 移动在test目录(必须存在)下,原文件名1.txt重名为2.txt fs.renameSync("./1.txt","./test/2.txt");
复制文件(单个),如果文件存在,默认覆盖旧文件(同步):fs.copyFileSync(src, dest[, mode])
fs.copyFileSync("./1.js","./2.js");
文件可读流:fs.createReadStream(path[, options])
let readSteam = fs.createReadStream("./img/1.jpg") readSteam.on("data",function(chunk){ console.log("data----",chunk.length) }) readSteam.on("end",function(){ console.log("end") }) readSteam.on("close",function(){ console.log("colse") }) readSteam.on("error",function(err){ console.log(err) })
文件可写流:fs.createWriteStream(path[, options])
let writeSteam = fs.createWriteStream("./writeSteam.txt") writeSteam.write("this is write data") writeSteam.end(); //需要关闭流 writeSteam.on("finish",function(){ console.log("finish") }) writeSteam.on("close",function(){ console.log("close") }) writeSteam.on("error",function(err){ console.log(err) })
可写流与可写流结合:
let out = fs.createReadStream('1.png') let iut = fs.createWriteStream("2.png") // 1方式一: 使用pip 管道流 // out.pipe(iut); // 2.方式二 写入流 out.on("data",function(chunk){ iut.write(chunk) }) out.on("end",function(){ iut.end(); //读取完毕,同时需要关闭写入流 }) out.on("error",function(err){ console.log(err) }) iut.on("finish",function(){ console.log("finish") })
以上都是总结常用的文件操作的api,可以在官方网站查到:http://nodejs.cn/
下面就封装几个也是常用的方法:
- 递归创建目录
- 深度删除目录/文件
- 深度复制目录/文件
递归创建目录 :
1 const fs = require("fs") 2 const path = require("path") 3 function mkdirSync(dirname) { 4 if (fs.existsSync(dirname)) { 5 return true; 6 } else { 7 if (mkdirSync(path.dirname(dirname))) { 8 fs.mkdirSync(dirname); 9 return true 10 } 11 } 12 } 13 //使用 14 mkdirSync("./test1/test2/test3");
深度删除目录:
1 const fs = require("fs") 2 function rm(pathname){ 3 try { 4 if(fs.existsSync(pathname)){ //检查路径是否存在 5 //检测是否目录路径还是文件 6 if(isDir(pathname)){ 7 let files = fs.readdirSync(pathname); 8 files.forEach(file=>{ 9 let filePath = pathname +'/'+file; //当前路径的(目录和文件) 10 if(isDir(filePath)){ 11 rm(filePath) 12 }else{ 13 // 删除文件 14 fs.existsSync(filePath)&&fs.unlinkSync(filePath) 15 console.log("--delele file--",filePath) 16 } 17 18 }) 19 fs.existsSync(pathname)&&fs.rmdirSync(pathname) 20 console.log("--delele dir--",pathname) 21 22 }else{ //文件 23 24 // 删除文件 25 fs.unlinkSync(pathname) 26 console.log("--delele file--",pathname) 27 28 } 29 30 31 }else{ 32 console.error("no such file or directory, stat '"+pathname+"'") 33 } 34 } catch (error) { 35 console.error(error) 36 } 37 38 } 39 40 function isDir(pathname){ 41 return fs.statSync(pathname).isDirectory() 42 } 43 44 //使用 45 rm("./test1");//该目录下有多级目录和文件
深度复制目录和文件:
1 const path = require("path") 2 const fs = require("fs") 3 4 function copy(frompath,topath){ 5 if(frompath==topath){ 6 return 7 } 8 if(fs.existsSync(frompath)){ 9 // 如果存在,判断是目录还是文件 10 if(isDir(frompath)){ 11 mkdirSync(topath); 12 let files = fs.readdirSync(frompath); 13 files.forEach(file=>{ 14 let fromFilePath = frompath +'/'+file; //当前目录的(目录和文件) 15 let toFilePath = topath+'/'+file; 16 if(isDir(fromFilePath)){ 17 // mkdirSync(toFilePath);//创建目录 18 copy(fromFilePath,toFilePath) //递归目录 19 }else{ 20 fs.copyFileSync(fromFilePath,toFilePath);//这里也可以流的方式来操作 21 } 22 }) 23 }else{ 24 fs.copyFileSync(frompath,topath) 25 } 26 27 }else{ 28 console.error("frompath no such file or directory, stat '"+frompath+"'") 29 } 30 31 32 33 } 34 35 function isDir(pathname){ 36 return fs.statSync(pathname).isDirectory() 37 } 38 // 递归创建目录 39 function mkdirSync(dirname) { 40 if (fs.existsSync(dirname)) { 41 return true; 42 } else { 43 if (mkdirSync(path.dirname(dirname))) { 44 fs.mkdirSync(dirname); 45 return true 46 } 47 } 48 } 49 //使用 50 copy("./src",'dist')