nodejs模块——fs模块 文件操作;nodejs文件操作

fs模块用于对系统文件及目录进行读写操作。

使用require('fs')载入fs模块,模块中所有方法都有同步和异步两种形式。

异步方法中回调函数的第一个参数总是留给异常参数(exception),如果方法成功完成,该参数为null或undefined。

1.****nodejs文件操作分为同步和异步请求。同步后面加了Sync
    //异步删除
    fs.unlink('/tmp/hello', (err) => {
      if (err) throw err;
      console.log('successfully deleted /tmp/hello');
    });
    //同步删除
    fs.unlinkSync('/tmp/hello');
    console.log('successfully deleted /tmp/hello');

2.**异步不保证顺序
    fs.rename('/tmp/hello', '/tmp/world', (err) => {
      if (err) throw err;
      console.log('renamed complete');
    });
    fs.stat('/tmp/world', (err, stats) => {
      if (err) throw err;
      console.log(`stats: ${JSON.stringify(stats)}`);
     //stats: {"dev":-593730986,"mode":33206,"nlink":1,"uid":0,"gid":0,
     //"rdev":0,"ino":2251799813714667,"size":3,"atime":"2016-03-25T07:41:15.892Z",
     //"mtime":"2016-03-25T07:41:19.870Z","ctime":"2016-03-25T07:42:00.065Z",
     //"birthtime":"2016-03-25T07:41:15.819Z"}

    });
    //下面可以保证
    fs.rename('/tmp/hello', '/tmp/world', (err) => {
      if (err) throw err;
      fs.stat('/tmp/world', (err, stats) => {
        if (err) throw err;
        console.log(`stats: ${JSON.stringify(stats)}`);
      });
    });

4.Class: fs.FSWatcher 类, 从fs.watch()方法返回
    (1)Event: 'change'
            event <String> 文件类型改变
            filename <String> 文件名改变
    (2)Event: 'error'3)watcher.close() 停止监听文件变化

5.Class: fs.ReadStream 类
    (1)Event: 'open' fd <Number> 整数文件描述符
        当ReadStream文件打开时触发
    (2)readStream.path 打开文件的路径

6.***Class: fs.Stats 类
    (1)对象从fs.stat(), fs.lstat()、 fs.fstat() 
        stats.isFile()
        stats.isDirectory()
        stats.isBlockDevice()
        stats.isCharacterDevice()
        stats.isSymbolicLink() (only valid with fs.lstat())
        stats.isFIFO()
        stats.isSocket()
        //例子
            fs.stat('input.txt', function (err, stats) {
           if (err) {
               return console.error(err);
           }
           console.log(stats);
           console.log("读取文件信息成功!");

           // 检测文件类型
           console.log("是否为文件(isFile) ? " + stats.isFile());
           console.log("是否为目录(isDirectory) ? " + stats.isDirectory());    
        });
    (2)对于普通文件 util.inspect(stats)会返回
        {
          dev: 2114,
          ino: 48064969,
          mode: 33188,
          nlink: 1,
          uid: 85,
          gid: 100,
          rdev: 0,
          size: 527,
          blksize: 4096,
          blocks: 8,
          atime: Mon, 10 Oct 2011 23:24:11 GMT, //Access Time"
          mtime: Mon, 10 Oct 2011 23:24:11 GMT, //Modified Time 数据改变
          ctime: Mon, 10 Oct 2011 23:24:11 GMT, //Change Time status 改变
          birthtime: Mon, 10 Oct 2011 23:24:11 GMT //创建日期
        }

7.Class: fs.WriteStream 文件写入流
    (1)Event: 'open' fd <Number> 整数文件描述符
        当WriteStream文件打开时触发
    (2)writeStream.bytesWritten 当现在为止已经写入的文件大小
    (3)writeStream.path 写入的路径

8.fs.access(path[, mode], callback)
    (1)mode类型
        fs.F_OK - 确定文件是否存在,默认,没有rwx权限
        fs.R_OK - 文件可读
        fs.W_OK - 文件可写
        fs.X_OK - 文件可执行 对于 Windows 没作用(will behave like fs.F_OK).
    (2)例子
        fs.access('/etc/passwd', fs.R_OK | fs.W_OK, (err) => {
              console.log(err ? 'no access!' : 'can read/write');
        });
    (3)同步,失败会抛出异常
        fs.accessSync(path[, mode])

9.***fs.appendFile(file, data[, options], callback) 添加文件
    (1)参数
        file <String> | <Number> filename 或者 file descriptor
        data <String> | <Buffer> 数据
        options <Object> | <String> 
            encoding <String> | <Null> default = 'utf8'
            mode <Number> default = 0o666
            flag <String> default = 'a'
        callback <Function>
    (2)例子
        fs.appendFile('message.txt', 'data to append','utf8', (err) => {
          if (err) throw err;
          console.log('The "data to append" was appended to file!');
        });
    (3)同步版本
        fs.appendFileSync(file, data[, options])

10.几个函数????
    fs.chmod(path, mode, callback)
    fs.chmodSync(path, mode)

    fs.chown(path, uid, gid, callback)#
    fs.chownSync(path, uid, gid)#

11.***关闭文件
    fs.close(fd, callback)
    fs.closeSync(fd)
    //例子
        var buf = new Buffer(1024);
        console.log("准备打开文件!");
        fs.open('input.txt', 'r+', function(err, fd) {
           if (err) {
               return console.error(err);
           }
           console.log("文件打开成功!");
           console.log("准备读取文件!");
           fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
              if (err){
                 console.log(err);
              }

              // 仅输出读取的字节
              if(bytes > 0){
                 console.log(buf.slice(0, bytes).toString());
              }

              // 关闭文件
              fs.close(fd, function(err){
                 if (err){
                    console.log(err);
                 } 
                 console.log("文件关闭成功");
              });
           });
        });

12.****fs.createReadStream(path[, options]) 返回ReadStream对象
    (1)options
        {
          flags: 'r',
          encoding: null, 
          fd: null, //若为非空,则忽略path,使用文件描述符,不会有open事件
          mode: 0o666,
          autoClose: true, //若为false则不会自动关闭
          start:Number, //字节开始
          end:Number//字节结束
        }
    (2)fs.createReadStream('sample.txt', {start: 90, end: 99});

     (3)源代码
        fs.createReadStream = function(path, options) {
           return new ReadStream(path, options);
        };
13.****fs.createWriteStream(path[, options]) 返回WriteStream
    (1)
        {
          flags: 'w',
          defaultEncoding: 'utf8',
          fd: null,
          mode: 0o666,
          autoClose: true
        }
    (2)源代码底层实现
        fs.createWriteStream = function(path, options) { 
          return new WriteStream(path, options);
        };
    (3)例子********
            var fs = require('fs'),
            path = require('path'),
            out = process.stdout;
            var filePath = 'x264-BATV.mkv';

            var readStream = fs.createReadStream(filePath);
            var writeStream = fs.createWriteStream('file.mkv');

            var stat = fs.statSync(filePath);

            var totalSize = stat.size;
            var passedLength = 0;
            var lastSize = 0;
            var startTime = Date.now();

            readStream.on('data', function(chunk) {
                passedLength += chunk.length;//获得已经复制的大小
                if (writeStream.write(chunk) === false) {
                    readStream.pause();
                }
            });

            readStream.on('end', function() {
                writeStream.end();
            });

            writeStream.on('drain', function() {
                readStream.resume();
            });

            setTimeout(function show() {
                var percent = Math.ceil((passedLength / totalSize) * 100);
                var size = Math.ceil(passedLength / 1000000);
                var diff = size - lastSize;
                lastSize = size;
                out.clearLine();
                out.cursorTo(0);
                out.write('已完成' + size + 'MB, ' + percent + '%, 速度:' + diff * 2 + 'MB/s');
                if (passedLength < totalSize) {
                    setTimeout(show, 500);
                } else {
                    var endTime = Date.now();
                    console.log();
                    console.log('共用时:' + (endTime - startTime) / 1000 + '秒。');
                }
            }, 500);
14.***创建目录
    fs.mkdir(path[, mode], callback) mode默认0o777
    fs.mkdirSync(path[, mode])
    //目录操作
    fs.mkdir('/tmp/test',function(err){
       if (err) {
           return console.error(err);
       }
       console.log("目录创建成功。");
    });
15.**fs.open(path, flags[, mode], callback) 打开文件
    (1)flags
        'r' - 读模式.文件不存在报异常
        'r+' - 读写.文件不存在报异常
        'rs' 同步读,跳过缓冲区 要同步用fs.openSync()
        'rs+' 同步读写
        'w' - 写模式. 文件不存在创建
        'wx' - 写模式. 路径存在则失败
        'w+' - 读写模式. 文件不存在创建    
        'wx+' - 读写模式. 路径存在则失败
        'a' - 添加. 文件不存在创建
        'ax' - 添加. 文件不存在失败
        'a+' - 读添加. 文件不存在创建
        'ax+' - 读添加. 文件不存在失败
    (2)mode 默认0666 可读写
    (3)回调函数包含两个参数 (err, fd)
    (4)fs.openSync(path, flags[, mode]) 同步方法

16.***fs.read(fd, buffer, offset, length, position, callback)
    根据文件描述符fd来读取文件,回调(err, bytesRead, buffer)
    //例子
    fs.open('input.txt', 'r+', function(err, fd) {
           if (err) {
               return console.error(err);
           }
           console.log("文件打开成功!");
           console.log("准备读取文件:");
           fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
              if (err){
                 console.log(err);
              }
              console.log(bytes + "  字节被读取");

              // 仅输出读取的字节
              if(bytes > 0){
                 console.log(buf.slice(0, bytes).toString());
              }
           });
        });

17.***fs.readdir(path, callback) 读目录 
    (1)回调(err, files)files是文件的目录数组
    (2)fs.readdirSync(path)同步方法

    (3)例子
        console.log("查看 /tmp 目录");
        fs.readdir("/tmp/",function(err, files){
           if (err) {
               return console.error(err);
           }
           files.forEach( function (file){
               console.log( file );
           });
        });
18.***fs.readFile(file[, options], callback) 度文件
     (1)
        file <String> | <Integer> filename or file descriptor
        options <Object> | <String>
        encoding <String> | <Null> default = null
        flag <String> default = 'r'
        callback <Function>
    (2)例子
        fs.readFile('/etc/passwd', 'utf8',(err, data) => {
          if (err) throw err;
          console.log(data);
        });
    (3)fs.readFileSync(file[, options])同步读
         返回文件的内容,如果制定encoding则返回字符串,否则返回buffer
         var source = fs.readFileSync('/path/to/source', {encoding: 'utf8'});
         fs.writeFileSync('/path/to/dest', source);

19. ***文件写操作
    fs.rename(oldPath, newPath, callback) callback只有一个err
    fs.renameSync(oldPath, newPath)
20.***删除目录
    fs.rmdir(path, callback)callback只有一个err
    fs.rmdirSync(path)#
    //例子
        console.log("准备删除目录 /tmp/test");
        fs.rmdir("/tmp/test",function(err){
           if (err) {
               return console.error(err);
           }
           console.log("读取 /tmp 目录");
           fs.readdir("/tmp/",function(err, files){
              if (err) {
                  return console.error(err);
              }
              files.forEach( function (file){
                  console.log( file );
              });
           });
        });

21.***列出文件属性
    fs.stat(path, callback)# 两个参数(err, stats) 
    fs.statSync(path) 返回fs.Stats.


20.***截取文件
    fs.truncate(path, len, callback) == fs.ftruncate(path,len,callback)//截断文件
    fs.truncateSync(path, len) 
    (1)例子
        var fs = require("fs");
        var buf = new Buffer(1024);

        console.log("准备打开文件!");
        fs.open('input.txt', 'r+', function(err, fd) {
           if (err) {
               return console.error(err);
           }
           console.log("文件打开成功!");
           console.log("截取10字节后的文件内容。");

           // 截取文件
           fs.ftruncate(fd, 10, function(err){
              if (err){
                 console.log(err);
              } 
              console.log("文件截取成功。");
              console.log("读取相同的文件"); 
              fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
                 if (err){
                    console.log(err);
                 }

                 // 仅输出读取的字节
                 if(bytes > 0){
                    console.log(buf.slice(0, bytes).toString());
                 }

                 // 关闭文件
                 fs.close(fd, function(err){
                    if (err){
                       console.log(err);
                    } 
                    console.log("文件关闭成功!");
                 });
              });
           });
        });

21.***fs.unwatchFile(filename[, listener])
     (1)停止监听文件变化
          fs.watch(filename[, options][, listener]) 
          options:{ persistent: true, recursive: false }.
          listener:(event, filename)
     (2)例子
            fs.watch('somedir', (event, filename) => {
              console.log(`event is: ${event}`);
              if (filename) {
                console.log(`filename provided: ${filename}`);
              } else {
                console.log('filename not provided');
              }
            });
22.***fs.watchFile(filename[, options], listener) 
     //文档中介绍原理是轮询(每隔一個固定的时间去检查文件是否改动)
    (1)options:{ persistent: true, interval: 5007 }.
    (2)例子
        fs.watchFile('message.text', (curr, prev) => {
          console.log(`the current mtime is: ${curr.mtime}`);
          console.log(`the previous mtime was: ${prev.mtime}`);
        });
        //watch()这个方法是通过监听操作系统提供的各种“事件”(内核发布的消息)实现的
        fs.watch() is more efficient than fs.watchFile

23.***写文件
    (1)fs.write(fd, data[, position[, encoding]], callback)
    (2)fs.writeFile(file, data[, options], callback)
     (4)同步方法
        fs.writeFileSync(file, data[, options])
        fs.writeSync(fd, buffer, offset, length[, position])
        fs.writeSync(fd, data[, position[, encoding]])

    (5)例子,重写会覆盖
        fs.writeFile('input.txt', '我是通过写入的文件内容!',  function(err) {
           if (err) {
               return console.error(err);
           }
           console.log("数据写入成功!");
           console.log("--------我是分割线-------------")
           console.log("读取写入的数据!");
           fs.readFile('input.txt', function (err, data) {
              if (err) {
                 return console.error(err);
              }
              console.log("异步读取文件数据: " + data.toString());
           });
        });

原文地址:https://www.cnblogs.com/lidongfeng/p/7506396.html