Node.js文件操作模块fs

 2015年05月28日    3758     声明


Node.js 提供一组类似UNIX(POSIX)标准的文件操作API,Node.js中操作文件的模块是fs(File System)模块,文件系统模块中的方法均有异步和同步版本。利用fs模块,可以查询文件的统计信息、打开关闭文件、读写文件等。

本文介绍一些fs模块的常用功能。相关功能有:

  1. 查询文件信息
  2. 打开文件
  3. 读取文件
  4. 写入文件
  5. 关闭文件
  6. 确定文件是否存在
  7. 文件删除
  8. 目录相关操作


1.查询文件信息:fs.stat(path, callback)

fs.stat()方法用于查询文件信息,可以用于查询文件的大小、创建时间、权限等相关信息。fs.stat()是异步方法,还有一个同步方法fs.statSync(path)。示例如下:

var fs = require('fs');

fs.stat('/Users/liuht/code/itbilu/demo/path.js', function (err, stats) {
    console.log(stats);
})

返回结果如下:

{ dev: 16777220,
  mode: 33188,
  nlink: 1,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 78808297,
  size: 244,
  blocks: 8,
  atime: Wed May 27 2015 18:24:43 GMT+0800 (CST),
  mtime: Wed May 27 2015 18:26:25 GMT+0800 (CST),
  ctime: Wed May 27 2015 18:26:25 GMT+0800 (CST) }

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

var fs = require('fs');

fs.stat('/Users/liuht/code/itbilu/demo/fs.js', function (err, stats) {
    console.log(stats.isFile()); 		//true
})

stats类中的方法有:

  • stats.isFile() 如果是标准文件,返回true。是目录、套接字、符号连接、或设备等返回false
  • stats. isDirectory() 如果是目录,返回true
  • stats. isBlockDevice() 如果是块设备,返回true,大多数情况下类UNIX系统的块设备都位于/dev目录下
  • stats. isCharacterDevice() 如果是字符设备,返回true
  • stats. isSymbolicLink() 如果是符号连接,返回true。(fs.lstat()方法返回的stats对象才有此方法)
  • stats.isFIFO() 如果是FIFO,返回true。FIFO是UNIX中的一种特殊类型的命令管道
  • stats. isSocket() 如果是UNIX套接字,返回true


2.打开文件:fs.open(path, flags[, mode], callback)

操作文件前需要选对文件进行打开操作。fs.open()方法用于打开文件,打开文件后,文件描述符fs会调用open方法的回调函数,然后就可以通过文件描述符fs对文件进行读写等操作了。同步版的方法名为fs.openSync(path, flags[, mode])。示例如下:

var fs = require('fs');

fs.open('/Users/liuht/code/itbilu/demo/path.js', 'r', function (err, fd) {
     // 可以在这里通过文件描述fs对文件进行操作
})

fs.open()方法第一个参数是文件路径。每二个参数是标志位,标志位表示文件的打开模式。标志含义与UNIX中fopen的标识位相同:

  • r 打开文本文件进行读取,数据流位置在文件起始处
  • r+ 打开文本文件进行读写,数据流位置在文件起始处
  • w 如果文件存在,将其清零,不存在创建写入文件。数据流位置在文件起始处
  • w+ 打开文件进行读写,如果文件存在,将其清零,不存在创建写入文件。数据流位置在文件起始处
  • a 打开文件写入数据,如果文件存在,将其清零,不存在创建写入文件。数据流位置在文件结尾处,此后的写操作都将数据追加到文件后面
  • a+ 打开文件进行文件读写,如果文件存在,将其清零,不存在创建写入文件。数据流位置在文件结尾处,此后的写操作都将数据追加到文件后面


3.读取文件信息:fs.read(fd, buffer, offset, length, position, callback)

文件打开后,就可以使用fs.read()方法进行读取,读取前需要创建一个用于保存文件数据的缓冲区。缓冲区数据最终会被传递到回调函数中。示例如下:

var fs = require('fs');

fs.open('/Users/liuht/code/itbilu/demo/fs.js', 'r', function (err, fd) {
    var readBuffer = new Buffer(1024),
	offset = 0,
	len = readBuffer.length,
	filePostion = 100;
    fs.read(fd, readBuffer, offset, len, filePostion, function(err, readByte){
	console.log('读取数据总数:'+readByte+' bytes' );		
	// ==>读取数据总数:239 bytes
        console.log(readBuffer.slice(0, readByte));     //数据已被填充到readBuffer中
    })

})

上面的代码,文件打开后,会从第100个字节开始,读取其后的1024个字节的数据。读取完成后,fs.read()会回调最后一个回调方法,然后就可以可以处理读取到的的缓冲的数据了。fs.openSync()是fs.open()方法的同步版本。

fs模块还提供了fs.readFile(filename[, options], callback)方法用于读取文件内容。


4.写入文件: fs.write(fd, buffer, offset, length[, position], callback)

文件打开后,可以通过 fs.write()方法传递一个数据缓冲区,以向打开的文件中写入数据。示例如下:

var fs = require('fs');

fs.open('./fs.txt', 'a', function (err, fd) {
    var writeBuffer = new Buffer('这是要写入的字符串'),
	offset = 0,
	len = writeBuffer.length,
	filePostion = null;

    fs.write(fd, writeBuffer, offset, len, filePostion, function(err, readByte){
	console.log('写数据总数:'+readByte+' bytes' );		
	// ==>写数据总数:27 bytes
    })
})

fs.writeSync()fs.write()方法的同步版本。

fs模块还提供了fs.writeFile(filename, data[, options], callback)方法可以方便的将字符串或Buffer数据写入文件。

提示:fs.read()和fs.write()方法执行后不要使用提供给其缓冲区Buffer,方法执行后缓冲区将处于这两个方法的控制下,只要回调函数执行后才能重新使用。


5.关闭文件:fs.close(fd, callback)

在前面读写文件的操作中,Node进程退出后就会关闭文件。在实际使用中,不能依靠进程退出来关闭文件,因此必须跟踪那些已打开的文件描述,在使用完毕后使用fs.close()方法关闭文件。示例如下:

var fs = require('fs');

fs.open('./fs.txt', 'a', function (err, fd) {
    //对文件一些操作
     
    //操作完成后,关闭文件
    fs.close(fd, function(err){
    })
})


6.确定文件是否存在:fs.exists(path, callback)

有时在文件进行操作之前,需要判断文件或路径是否存在。fs.exists()用于判断文件是否存在,fs.existsSync()是其同步版本。示例如下:

var fs = require('fs');

fs.exists('/etc/passwd', function (exists) {
  util.debug(exists ? "文件存在" : "文件不存在啊!");
});

注意:Node V4.0以后这个方法已经不再支持,请使用fs.stat()或fs.access()


不在使用的文件可以用fs.unlink()方法进行删除,删除前应使用fs.exists()方法检查文件是否存在,fs.unlinkSync()是其同步版本。示例如下:

var fs = require('fs');
var path = require('path');

var file = path.join(__dirname, './fs.txt');
if(fs.existsSync(file)){
    fs.unlink(file, function(err){
	if(err)
	{
  	    console.log(err);
	}
    })	
}


8.目录操作:fs.readdir(path, callback)fs.mkdir(path[, mode], callback)fs.rmdir(path, callback)

fs模块对目录的操作主要有:fs.readdir(),读取文件夹下所有文件名。fs.mkdir(),创建目录。fs.rmdir(),删除目录。fs.mkdir()创建目录时有第二个可选参数用于指定目录权限,不指定是权限为0777。这三个方法都sync同步方法。示例如下:

var fs = require('fs');
var path = require('path')
//读取目录夹内容
fs.readdir('./', function(err, files){
    if(err)console.log(err);
    console.log(files);
})	
//目录创建
fs.mkdir(path.join(__dirname, './test'), function(err){
    if(err) console.log(err);
})
//目录删除
fs.rmdir(path.join(__dirname, './test'), function(err){
    if(err) console.log(err);
})

以上是fs模块的常用功能,更多功能请查看:File System