node的内置模块 fs(入门进阶三)

fsfilesystem的缩写,该模块提供本地文件的读写能力,基本上是POSIX文件操作命令的简单包装。但是,这个模块几乎对所有操作提供异步和同步两种操作方式,供开发者选择。

注 : POSIX表示可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX )。POSIX标准意在期望获得源代码级别的软件可移植性。换句话说,为一个POSIX兼容的操作系统编写的程序,应该可以在任何其它的POSIX操作系统(即使是来自另一个厂商)上编译执行。

1、readFile()、readFileSync()

fs.readFile('./image.png', function (err, buffer) {

    if (err) throw err;
    process(buffer);

}

参数一:文件的路径,可以是绝对路径,也可以是相对路径。注意,如果是相对路径,是相对于当前进程所在的路径(process.cwd()),而不是相对于当前脚本所在的路径。

参数二:读取完成后的回调函数。该函数的第一个参数是发生错误时的错误对象,第二个参数是代表文件内容的Buffer实例。

fs.readFileSync(fileName, 'utf8');

readFileSync方法用于同步读取文件,返回一个字符串

参数一:文件路径

参数二:表示配置的对象,也可以是一个表示文本文件编码的字符串。默认的配置对象是{ encoding: null, flag: 'r' },即文件编码默认为null,读取模式默认为r(只读)。如果第二个参数不指定编码(encoding),readFileSync方法返回一个Buffer实例,否则返回的是一个字符串。

扫描二维码关注公众号,回复: 6182042 查看本文章
//input.txt内容 : 菜鸟教程官网地址:www.runoob.com

//file.js
var fs = require("fs");
// 异步读取
fs.readFile('input.txt', function (err, data) {
   if (err) {
       return console.error(err);
   }
   console.log("异步读取: " + data.toString());
});
// 同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());

console.log("程序执行完毕。");

$ node file.js

同步读取: 菜鸟教程官网地址:www.runoob.com

程序执行完毕。

异步读取: 菜鸟教程官网地址:www.runoob.com

2、writeFile()、writeFileSync()

fs.writeFile('message.txt', 'Hello Node.js'[, options], (err) => {
  if (err) throw err;
  console.log('It\'s saved!');
});

异步写入文件。

参数一 : 写入的文件名

参数二 : 写入的字符串

参数三 : 可选。该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w'

参数四 : 回调函数

回调函数前面,还可以再加一个参数,表示写入字符串的编码(默认是utf8

fs.writeFileSync(fileName, str, 'utf8');

同步写入文件。

参数一 : 文件路径

参数二 : 写入文件的字符串

参数三 : 文件编码,默认为utf8

3、exists(path, callback) : 用来判断给定路径是否存在,然后不管结果如何,都会调用回调函数

注 : 不要在open方法之前调用exists方法,open方法本身就能检查文件是否存在

fs.exists('/path/to/file', function (exists) {
  util.debug(exists ? "it's there" : "no file!");
});
//函数的参数是个表示文件是否存在的布尔值
//下面的例子是如果给定目录存在,就删除它
if (fs.existsSync(outputFolder)) {
  console.log('Removing ' + outputFolder);
  fs.rmdirSync(outputFolder);
}

4、open()、close()

fs.open(path, flags[, mode], callback)

path - 文件的路径。

flags - 文件打开的行为。具体值详见下文。

mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。

callback - 回调函数,带有两个参数如:callback(err, fd)。

r 以读取模式打开文件。如果文件不存在抛出异常。
r+ 以读写模式打开文件。如果文件不存在抛出异常。
rs 以同步的方式读取文件。
rs+ 以同步的方式读取和写入文件。
w 以写入模式打开文件,如果文件不存在则创建。
wx 类似 'w',但是如果文件路径存在,则文件写入失败。
w+ 以读写模式打开文件,如果文件不存在则创建。
wx+ 类似 'w+', 但是如果文件路径存在,则文件读写失败。
a 以追加模式打开文件,如果文件不存在则创建。
ax 类似 'a', 但是如果文件路径存在,则文件追加失败。
a+ 以读取追加模式打开文件,如果文件不存在则创建。
ax+ 类似 'a+', 但是如果文件路径存在,则文件读取追加失败。
fs.close(fd, callback)

fd - 通过 fs.open() 方法返回的文件描述符。

callback - 回调函数,没有参数。

 
fs.read(fd, buffer, offset, length, position, callback)

fd - 通过 fs.open() 方法返回的文件描述符。

buffer - 数据写入的缓冲区。

offset - 缓冲区写入的写入偏移量。

length - 要从文件中读取的字节数。

position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。

callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。

//input.txt 文件内容为:菜鸟教程官网地址:www.runoob.com

//file.js 文件内容
var fs = require("fs");
var buf = new Buffer.alloc(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);
      }
      console.log(bytes + "  字节被读取");
      
      // 仅输出读取的字节
      if(bytes > 0){
         console.log(buf.slice(0, bytes).toString());
      }
   });
});

$ node file.js 
准备打开已存在的文件!
文件打开成功!
准备读取文件:
42  字节被读取
菜鸟教程官网地址:www.runoob.com
var fs = require("fs");
var buf = new Buffer.alloc(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("文件关闭成功");
      });
   });
});
$ node file.js 
准备打开文件!
文件打开成功!
准备读取文件!
菜鸟教程官网地址:www.runoob.com
文件关闭成功

5、mkdir()、writeFile()、readFile() && mkdirSync()、writeFileSync()、readFileSync()

fs.mkdir('./helloDir'【,options】, function (err) {
   if (err) throw err;
});

用于新建目录。

参数一 : 目录名

参数二 : options 参数可以是:

     recursive - 是否以递归的方式创建目录,默认为 false。

     mode - 设置目录权限,默认为 0777。

参数三 : 回调函数,没有参数

fs.mkdirSync('./helloDirSync',0777);  
fs.writeFile('./helloDir/message.txt', 'Hello Node', function (err) {
   if (err) throw err;
   console.log('文件写入成功');
});

用于写入文件。

fs.writeFileSync('./helloDirSync/message.txt', 'Hello Node');  
fs.readFile('./helloDir/message.txt','UTF-8' ,function (err, data) {
   if (err) throw err;
   console.log(data);
});

用于读取文件内容。异步操作,不能同时发起多个readFile请求,否则会很快耗尽系统资源

参数一:文件名

参数二:文件编码,可用的文件编码包括“ascii”、“utf8”和“base64”。如果没有指定文件编码,返回的是原始的缓存二进制数据,这时需要调用buffer对象的toString方法,将其转为字符串

参数三 : 回调函数

fs.readFileSync('./helloDirSync/message.txt','UTF-8');  
var fs = require("fs");
// tmp 目录必须存在
console.log("创建目录 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("目录创建成功。");
});
//创建目录 /tmp/test/
//目录创建成功。

//可以添加 recursive: true 参数,不管创建的目录 /tmp 和 /tmp/a 是否存在
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
  if (err) throw err;
});

6、readdir()、readdirSync() : 读取目录

fs.readdir(path, callback)

path - 文件路径。

callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。

//file.js文件内容
var fs = require("fs");

console.log("查看 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
   if (err) {
       return console.error(err);
   }
   files.forEach( function (file){
       console.log( file );
   });
});

//查看 /tmp 目录
//input.out
//output.out
//test
//test.txt
fs.readdir(process.cwd(), function (err, files) {
  if (err) {
    console.log(err);
    return;
  }
  var count = files.length;
  var results = {};
  files.forEach(function (filename) {
    fs.readFile(filename, function (data) {
      results[filename] = data;
      count--;
      if (count <= 0) {
        // 对所有文件进行处理
      }
    });
  });
});
var files = fs.readdirSync(dir);
files.forEach(function (filename) {
  var fullname = path.join(dir,filename);
  var stats = fs.statSync(fullname);
  if (stats.isDirectory()) filename += '/';
  process.stdout.write(filename + '\t' +
    stats.size + '\t' +
    stats.mtime + '\n'
  );
});

7、rmdir()

fs.rmdir(path, callback)

path - 文件路径。

callback - 回调函数,没有参数。

//file.js文件内容
var fs = require("fs");
// 执行前创建一个空的 /tmp/test 目录
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 );
      });
   });
});
//准备删除目录 /tmp/test
//读取 /tmp 目录
//……

8、stat() : 判断正在处理的到底是一个文件,还是一个目录。它的参数是一个文件或目录,它产生一个对象,该对象包含了该文件或目录的具体信息

fs.stat(path, callback)

fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性

path - 文件路径。

callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。

fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
    console.log(stats);
    //{ dev: 16777220,mode: 33188,nlink: 1,uid: 501,gid: 20,rdev: 0,blksize: 4096,
    //  ino: 40333161,size: 61,blocks: 8,atime: Mon Sep 07 2015 17:43:55 GMT+0800 
    //  (CST),mtime: Mon Sep 07 2015 17:22:35 GMT+0800 (CST),ctime: Mon Sep 07 2015 
    //  17:22:35 GMT+0800 (CST) 
    //}
    console.log(stats.isFile()); //true
})
stats.isFile() 如果是文件返回 true,否则返回 false。
stats.isDirectory() 如果是目录返回 true,否则返回 false。
stats.isBlockDevice() 如果是块设备返回 true,否则返回 false。
stats.isCharacterDevice() 如果是字符设备返回 true,否则返回 false。
stats.isSymbolicLink() 如果是软链接返回 true,否则返回 false。
stats.isFIFO() 如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。
stats.isSocket() 如果是 Socket 返回 true,否则返回 false。
fs.readdir('/etc/', function (err, files) {
  if (err) throw err;

  files.forEach( function (file) {
    fs.stat('/etc/' + file, function (err, stats) {
      if (err) throw err;

      if (stats.isFile()) {
        console.log("%s is file", file);
      }
      else if (stats.isDirectory ()) {
      console.log("%s is a directory", file);
      }
    console.log('stats:  %s',JSON.stringify(stats));
    });
  });
});

9、ftruncate() : 截取文件

fs.ftruncate(fd, len, callback)

fd - 通过 fs.open() 方法返回的文件描述符。

len - 文件内容截取的长度。

callback - 回调函数,没有参数。

//input.txt 文件内容为:site:www.runoob.com

//file.js文件内容
var fs = require("fs");
var buf = new Buffer.alloc(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("文件关闭成功!");
         });
      });
   });
});

 $ node file.js
准备打开文件!
文件打开成功!
截取10字节内的文件内容,超出部分将被去除。
文件截取成功。
读取相同的文件
site:www.r
文件关闭成功

10、unlink() : 删除文件

fs.unlink(path, callback)

path - 文件路径。

callback - 回调函数,没有参数。

//input.txt 文件内容为:site:www.runoob.com

//file.js文件内容
var fs = require("fs");

console.log("准备删除文件!");
fs.unlink('input.txt', function(err) {
   if (err) {
       return console.error(err);
   }
   console.log("文件删除成功!");
});
$ node file.js 
准备删除文件!
文件删除成功!

11、watchfile() : 监听一个文件,如果该文件发生变化,就会自动触发回调函数。

        unwatchfile() : 用于解除对文件的监听。  

var fs = require('fs');

fs.watchFile('./testFile.txt', function (curr, prev) {
  console.log('the current mtime is: ' + curr.mtime);
  console.log('the previous mtime was: ' + prev.mtime);
});

fs.writeFile('./testFile.txt', "changed", function (err) {
  if (err) throw err;

  console.log("file write complete");   
});

12、createReadStream() : 往往用于打开大型的文本文件,创建一个读取操作的数据流。所谓大型文本文件,指的是文本文件的体积很大,读取操作的缓存装不下,只能分成几次发送,每次发送会触发一个data事件,发送结束会触发end事件。

function readLines(input, func) {
  var remaining = '';

  input.on('data', function(data) {
    remaining += data;
    var index = remaining.indexOf('\n');
    var last  = 0;
    while (index > -1) {
      var line = remaining.substring(last, index);
      last = index + 1;
      func(line);
      index = remaining.indexOf('\n', last);
    }

    remaining = remaining.substring(last);
  });

  input.on('end', function() {
    if (remaining.length > 0) {
      func(remaining);
    }
  });
}

function func(data) {
  console.log('Line: ' + data);
}

var input = fs.createReadStream('lines.txt');
readLines(input, func);

13、createWriteStream() : 创建一个写入数据流对象,该对象的write方法用于写入数据,end方法用于结束写入操作。

var out = fs.createWriteStream(fileName, {
  encoding: 'utf8'
});
out.write(str);
out.end();

createWriteStream方法和createReadStream方法配合,可以实现拷贝大型文件。

function fileCopy(filename1, filename2, done) {
  var input = fs.createReadStream(filename1);
  var output = fs.createWriteStream(filename2);

  input.on('data', function(d) { output.write(d); });
  input.on('error', function(err) { throw err; });
  input.on('end', function() {
    output.end();
    if (done) done();
  });
}

猜你喜欢

转载自blog.csdn.net/weixin_43586120/article/details/89925852