博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
node.js 文件操作
阅读量:7102 次
发布时间:2019-06-28

本文共 10190 字,大约阅读时间需要 33 分钟。

既然到了后台,只要你有权限就可以为所欲为了!

创建文件夹

//fs.jsvar fs = require('fs');fs.mkdirSync('a', 0755);fs.mkdirSync('a/b', 0755);fs.mkdirSync('a/b/c', 0755);

那么它会在fs.js所在目录中创建一个a目录,a目录下再创建b目录,b目录下创建c目录。mkdirSync是一个同步方法,拥有三个参数,第一个是路径,第二个是,第三个是回调

但这样做有点不妥,如果指定目录已存在,就报错。如果要建立多级目录,一层层判定此目录是否存在,立即会陷入“回调地狱”的境地。虽然node.js对于IO操作的方法都提供了两个版本,一个是同步的,一个是异步的。想了想,搞出我自己的mkdirSync函数,实现比的作者好很多。

var fs = require('fs');function mkdirSync(url,mode,cb){    var path = require("path"), arr = url.split("/");    mode = mode || 0755;    cb = cb || function(){};    if(arr[0]==="."){//处理 ./aaa        arr.shift();    }    if(arr[0] == ".."){//处理 ../ddd/d        arr.splice(0,2,arr[0]+"/"+arr[1])    }    function inner(cur){        if(!path.existsSync(cur)){//不存在就创建一个            fs.mkdirSync(cur, mode)        }        if(arr.length){            inner(cur + "/"+arr.shift());        }else{            cb();        }    }    arr.length && inner(arr.shift());}//测试代码mkdirSync("aaa/ddd/dd",0,function(e){    if(e){        console.log('出错了');    }else{        console.log("创建成功")    }});

有关目录的创建的讨论,详见

创建文件与写入内容

创建文件的方法fs.open(path, flags, [mode], [callback])好像所有语言都很一致,可能是想与最原始的C语言的方法保持一致。这是个异步方法,其同步版本,与其他同步方法一样,就是少了个回调。说一下flags中w与a的不同,w会把已存在的同名文件删除再创建一个,因此要注意。

fs.open("test.txt", "w");

写入内容。这有几种方法,比如fs.write,不过它的第一个参数要求类型为Buffer,而fs.openSync不是返回一个Buffer,因此它不能与fs.write配合使用。

//fs.jsvar fs = require('fs');fs.open("test.txt","w",0644,function(e,fd){    if(e) throw e;    fs.write(fd,"first fs!",0,'utf8',function(e){        if(e) throw e;        fs.closeSync(fd);    })});

这时,我们就创建一个文本文件,里面写入"first fs"。不过open中间那两个参数的不是必要的。我们可以再搞一个fs2.js脚本

//fs2.jsvar fs = require('fs');fs.open("test.txt","a",0644,function(e,fd){    if(e) throw e;    fs.write(fd,"second fs!",function(e){        if(e) throw e;        fs.closeSync(fd);    })});

执行它,它会在test.txt追加"second fs"这句话。

fs的open, write, close有点像我们在浏览器对document的操作。此外,还有fs.writeFile与fs.writeFileSync,可惜它们不能做追加内容的操作。

var fs = require('fs');fs.writeFile("test.txt","third fs!",function(e){//会先清空原先的内容    if(e) throw e;})

删除目录或文件

var fs = require('fs');fs.rmdir("aaa",function(e){    if(e){        console.log(e)    }})/**{ stack: [Getter/Setter],  arguments: undefined,  type: undefined,  message: 'ENOTEMPTY, Directory not empty \'aaa\'',  errno: 39,  code: 'ENOTEMPTY',  path: 'aaa' }*/

报错,缘由是之前我们还为aaa创建了子目录,必须逐个删除,实在不人性化,于是又造了一个轮子。

var fs = require('fs');var rmdirSync = (function(){    function iterator(url,dirs){        var stat = fs.statSync(url);        if(stat.isDirectory()){            dirs.unshift(url);//收集目录            inner(url,dirs);        }else if(stat.isFile()){            fs.unlinkSync(url);//直接删除文件        }    }    function inner(path,dirs){        var arr = fs.readdirSync(path);        for(var i = 0, el ; el = arr[i++];){            iterator(path+"/"+el,dirs);        }    }    return function(dir,cb){        cb = cb || function(){};        var dirs = [];        try{            iterator(dir,dirs);            for(var i = 0, el ; el = dirs[i++];){                fs.rmdirSync(el);//一次性删除所有收集到的目录            }            cb()        }catch(e){//如果文件或目录本来就不存在,fs.statSync会报错,不过我们还是当成没有异常发生            e.code === "ENOENT" ? cb() : cb(e);        }    }})();rmdirSync("aaa",function(e){    console.log("!!!"+e)    console.log("删除aaa目录以及子目录成功")})

上面的rmdirSync还可以分解出一个方法,取得给定目录下的所有目录与文件。

var fs = require('fs');var getAllFolersAndFiles = (function(){    function iterator(url, folders, files){        var stat = fs.statSync(url);        if(stat.isDirectory()){            folders.unshift(url);//收集目录            inner(url,folders, files);        }else if(stat.isFile()){            files.unshift(url);//收集文件        }    }    function inner(path,folders,files){        var arr = fs.readdirSync(path);        for(var i = 0, el ; el = arr[i++];){            iterator(path+"/"+el,folders,files);        }    }    return function(dir){        var folders = [], files = [];        try{            iterator(dir,folders,files);        }catch(e){        }finally{            return {                folders : folders,                files   : files            }        }    }})()

如果我们只想取得指定目下的所有文件,还可以更精简些!

function getAllFiles(root) {  var result = [], files = fs.readdirSync(root)  files.forEach(function(file) {    var pathname = root+ "/" + file      , stat = fs.lstatSync(pathname)    if (stat === undefined) return    // 不是文件夹就是文件    if (!stat.isDirectory()) {      result.push(pathname)    // 递归自身    } else {      result = result.concat(getAllFiles(pathname))    }  });  return result}

监听文件的改动

就是使用watchFile及其同步版本。

var fs = require("fs"),sys = require("util");fs.open("aaa.js","w",0644,function(e,fd){    fs.writeSync(fd,"console.log(1111);");    fs.closeSync(fd);})fs.watchFile("aaa.js", function(curr, prev) {  sys.puts("\n\ttest_file.txt has been edited");  sys.puts("\tThe current mtime is: " + curr.mtime);  sys.puts("\tThe previous mtime was: " + prev.mtime + "\n");});fs.open("aaa.js","a",0644,function(e,fd){    fs.writeSync(fd,"console.log(2222)");    fs.closeSync(fd);});

此外,node.js还提供了修改了目录文件权限的操作,但这些都是不值一提。自己看看文档就会了。

//合并脚本var fs = require("fs")var path = require("path") //不同的操作系统,其 文件目录 分割符是不一样的,不能直接使用 + "/"来实现var curDir = process.cwd() //当前目录var otherDir = curDir.replace(/avalon[\/\\]src/, "")console.log("otherDir " + otherDir)var Buffer = require('buffer').Buffervar now = new Datevar date = now.getFullYear() + "." + now.getMonth() + "." + now.getDate()function directive(name) {    return path.join("15 directive", name)}//avalon.js 所需要合并的子文件var compatibleFiles = [    "00 inter", "01 variable", "01 variable.share", "02 core", "03 es5.shim",    "04 dom.polyfill", "05 configuration", "06 EventBus", "06 findNodes",    "07 modelFactory", "07 modelFactory.shim", "08 Collection", "09 dispatcher",    "10 HTML", "12 scan", "12 scanTag", "12 scanNode", "12 scanAttr", "12 scanText",    "13 dom", "14 parser", "14 parser.share",    directive("skip"), directive("controller"), directive("important"),    directive("attr"), directive("include"), directive("class.hover.active"), directive("data"),    directive("text"), directive("html"), directive("if"), directive("visible"), directive("on"),    directive("widget"), directive("duplex.1"), directive("duplex.2"),    directive("duplex.3"), directive("repeat.each.with"),    "16 filter", "17 loader", "18 domReady", "19 outer"]//avalon.modern.js 所需要合并的子文件var modernFiles = [    "00 inter", "01 variable.modern", "01 variable.share", "02 core.modern",    "04 dom.polyfill.modern", "05 configuration", "06 EventBus", "06 findNodes.modern",    "07 modelFactory", "08 Collection", "09 dispatcher", "10 HTML.modern",    "12 scan", "12 scanTag", "12 scanNode", "12 scanAttr.modern", "12 scanText",    "13 dom.modern", "14 parser.modern", "14 parser.share",    directive("skip"), directive("controller"), directive("important"),    directive("attr"), directive("include"), directive("class.hover.active"), directive("data"),    directive("text.modern"), directive("html"), directive("if"), directive("visible"), directive("on"),    directive("widget"), directive("duplex.1"), directive("duplex.2.modern"),    directive("duplex.3"), directive("repeat.each.with"),    "16 filter", "17 loader", "18 domReady.modern", "19 outer"]//avalon.shim.js 所需要合并的子文件var shimFiles = [    "00 inter", "01 variable", "01 variable.share", "02 core", "03 es5.shim",    "04 dom.polyfill", "05 configuration", "06 EventBus", "06 findNodes",    "07 modelFactory", "07 modelFactory.shim", "08 Collection", "09 dispatcher",    "10 HTML", "12 scan", "12 scanTag", "12 scanNode", "12 scanAttr", "12 scanText",    "13 dom", "14 parser", "14 parser.share",    directive("skip"), directive("controller"), directive("important"),    directive("attr"), directive("include"), directive("class.hover.active"), directive("data"),    directive("text"), directive("html"), directive("if"), directive("visible"), directive("on"),    directive("widget"), directive("duplex.1"), directive("duplex.2"),    directive("duplex.3"), directive("repeat.each.with"),    "16 filter", "18 domReady.noop", "19 outer"]var writable = fs.createWriteStream(path.join(curDir, 'avalon.js'), {    encoding: "utf8"});writable.setMaxListeners(100) //默认只有添加11个事件,很容易爆栈compatibleFiles.forEach(function(fileName) {    var filePath = path.join(curDir, fileName + ".js")    var readable = fs.createReadStream(filePath)    if (fileName == "00 inter") {        readable.on('data', function(chunk) {            var str = chunk.toString("utf8")            var offset = (new Buffer(str.slice(0, str.indexOf("!!")), "utf8")).length            chunk.write(" build in " + date + " \n", offset)        })    }    //  readable.push("//都会插到新文件的最前面")    //  writable.write("//都会插到新文件的最前面 ")    readable.pipe(writable)    readable.on("readable", function() {        writable.write("\n")        console.log("add " + filePath)    })    //更新avalon.test中的文件    writable.on("finish", function() {        var readable3 = fs.createReadStream(path.join(curDir, 'avalon.js'))        var writable3 = fs.createWriteStream(path.join(otherDir, 'avalon.test', "src", "avalon.js"))        readable3.pipe(writable3)    });})var writable2 = fs.createWriteStream(path.join(curDir, 'avalon.modern.js'), {    encoding: "utf8"})writable2.setMaxListeners(100) //默认只有添加11个事件,很容易爆栈modernFiles.forEach(function(fileName) {    var filePath = path.join(curDir, fileName + ".js")    var readable = fs.createReadStream(filePath)    if (fileName == "00 inter") {        readable.on('data', function(chunk) {            var str = chunk.toString("utf8")            var offset = (new Buffer(str.slice(0, str.indexOf("!!")), "utf8")).length            chunk.write(" build in " + date + " \n", offset)        })    }    //  readable.push("//都会插到新文件的最前面")    //  writable.write("//都会插到新文件的最前面 ")    readable.pipe(writable2)    readable.on("readable", function() {        writable2.write("\n")        console.log("add " + filePath)    })    //更新avalon.test中的文件    writable2.on("finish", function() {        var readable3 = fs.createReadStream(path.join(curDir, 'avalon.modern.js'))        var writable3 = fs.createWriteStream(path.join(otherDir, 'avalon.test', "src", "avalon.modern.js"))        readable3.pipe(writable3)    });})

转载地址:http://evkhl.baihongyu.com/

你可能感兴趣的文章
Linux下Jenkins服务器搭建
查看>>
pavenet资源
查看>>
致研究者:2018 AI 研究趋势
查看>>
006-unity3d GUI初识、贴图、自定义鼠标指针
查看>>
Set replication in Hadoop
查看>>
Linux - 进程与内存查看
查看>>
高性能爬虫——asynicio模块
查看>>
Docker容器的数据卷(data volume),数据卷容器,数据卷的备份和还原。
查看>>
win10 字体渲染优化 色彩调整
查看>>
分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
查看>>
VC++:ActiveX Test Container
查看>>
iOS知识点汇总
查看>>
butterknife用法总结
查看>>
Win8 Metro(C#)数字图像处理--2.55OSTU法图像二值化
查看>>
ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上)
查看>>
Service Fabric本地开发部署修改数据目录
查看>>
php面试题
查看>>
Hexo NexT 博客本地搭建指南
查看>>
快速使用CSS Grid布局,实现响应式设计
查看>>
这并不是习惯,而是忍耐力变强了
查看>>