node.js 文件操作

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

创建文件夹

//fs.js
var 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函数,实现比mkdirp的作者好很多。

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.js
var 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.js
var 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还提供了修改了目录文件权限的操作,但这些都是不值一提。自己看看文档就会了。
原帖地址:http://www.cnblogs.com/rubylouvre/archive/2011/11/28/2264717.html
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值