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()); }); });