Node文件系统

Node 通过封装基本的POSIX函数来提供文件系统,使用require('fs')来使用这个模块,所有与文件相关的方法,都提供了异步和同步的形式。 异步的方法通常会将一个可选的回调函数作为最后一个参数,回调函数的第一个参数通常留给意外情况,如果操作是成功的,第一个参数将是null或者undeefined。 使用同步方法,对于任何意外都会即时抛出,可以使用try/catch语句来处理意外情况,或者让错误时间向上冒泡。 下面是一个有关异步方法的基本例子:

const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('sucessfully deleted /tmp/hello');
}

再跟着一个同步的例子:

const fs = require('fs');
fs.unlink('/tmp/hello');
console.log('successfully deleted /tmp/hello');

使用异步方法时,需要注意异步方法的执行不一定按照书写顺序,比如下面这种写法很容易出错:

fs.rename('/tmp/hello', '/tmp/world', (err) => {
   if (err) throw err;
   console.log('renamed compelte');
});

fs.stat('/tmp/world', (err, stats) => {if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`)});

在这里,很可能fs.stat函数先于fs.rename,这样会出现一些不必要的错误,正确的方法应该是写在回调函数中。

fs.rename('/tmp/hello/', '/tmp/world', (err) ss=> {
    if (err) throw err;
    fs.stat('/tmp/world'),(err, stats) => {
        console.log(`stats: ${JSON.stringfy(stats)});
    });
});

执行复杂耗时的方法,强烈建议使用异步版本,同步方法在它们执行结束之前,会一直锁住当前线程,阻断所有操作。 在fs模块中,可以使用相对路径,但是需要留意参照的路径来自于process.cwd()的返回值。 很多fs函数可以忽略掉回调参数,如果这样进行使用,默认会抛出错误,为了跟踪到函数调用的位置,可以设置NODE_DEBUG环境变量:

$ cat script.js
function bad() {
  require('fs').readFile('/');ssss
}
bad();

$ env NODE_DEBUG=fs node script.js
fs.js:66
        throw err;
              ^
Error: EISDIR, read
    at rethrow (fs.js:61:21)
    at maybeCallback (fs.js:79:42)
    at Object.fs.readFile (fs.js:153:18)
    at bad (/path/to/script.js:2:17)
    at Object.<anonymous> (/path/to/script.js:5:1)
    <etc.>

fs.watch(filename[, options][, listener]) 监听制定文件或者目录的变化情况,filename参数可以是文件或者目录,这个方法返回一个fs.FSWather对象。 第二个参数是可选的,提供的options参数应该是一个对象,里面要求的成员是persistentrecursive,这个两个成员都是布尔类型的值。 用做监听的回调函数有两个参数,分别是(event, filename)event的值视情况,返回字符串changerename,文件名指的是触发事件的这个文件。看下面的这个例子:

// node.md
// 被监听的文件
this is cat.

// app.js
// 用来监听文件改变
    fs.watch('./node.md', (event, filename) => {
        console.log('下面是event参数,event参数的类型,filename');
        console.log(typeof event);
        console.log(filename);
    });

// node.md
// 这里修改了监听的node.md文件
this is dog.

// console
// 执行结果
下面是event参数,event参数的类型,filename
change
string
node.md

// node.md => node1.md
// 修改文件的名字

// console
// 执行结果
下面是event参数,event参数的类型,filename
rename
string
node1.md

注意事项: fs.watch并不是跨所有平台的,在某些常见下不一定可用。 第二个参数中的布尔值recursive只在osx和window下可以使用。

可用性:

  • fs.watch依赖于操作系统底层模块,由操作系统底层模块通知Node文件的变化。

  • 如果某个操作系统底层模块对于文件的监听本身就有问题,那么fs.watch是无法发挥作用的,比如监听了一些不可靠的目录和文件,网络文件系统,虚拟机系统中的文件。

  • 在linux,osx系统中,fs.watch解析路径成一个索引节点,并且监听这个节点,但是如果监听的节点被删除或者重新创建,那么此时它就成了一个新节点了,watch将会发送一个delete事件,但是仍然监听原来的节点,原来的事件不会响应新节点的改变,这种处理是符合预期的。

  • filename参数只支持在linux和windows上面指定(osx也可以,但是有些情况可能会有异常),事实上,即便是在可以使用的平台上,也不建议直接使用这个参数,因为在回调函数内部,建议增加一些逻辑判断,看一下filename是否为null,如下面的例子:

    fs.watch('somedir', (event, filename) => {
        console.log(`event is: ${event}`);
        if (filename) {
             console.log(`filename provided: ${filename}`);
         } else {
             console.log('filename not provided');
         }
    });
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容