node.js 文件操作

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还提供了修改了目录文件权限的操作,但这些都是不值一提。自己看看文档就会了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值