前面的博客 Node.js文件操作一中主要是对文件的读写操作,其实还有文件这块还有一些其他操作.
一、验证文件path是否正确(系统是如下定义的)
fs.exists = function(path, callback) { if (!nullCheck(path, cb)) return; var req = new FSReqWrap(); req.oncomplete = cb; binding.stat(pathModule._makeLong(path), req); function cb(err, stats) { if (callback) callback(err ? false : true); } }; fs.existsSync = function(path) { try { nullCheck(path); binding.stat(pathModule._makeLong(path)); return true; } catch (e) { return false; } };
二、获取文件信息
获取文件信息用fs.stats(path,callback)、fs.statsSync(path),它们返回Stats对象.下面是系统定义的Stats对象.
// Static method to set the stats properties on a Stats object. fs.Stats = function( dev, mode, nlink, uid, gid, rdev, blksize, ino, size, blocks, atim_msec, mtim_msec, ctim_msec, birthtim_msec) { this.dev = dev; this.mode = mode; this.nlink = nlink; this.uid = uid; this.gid = gid; this.rdev = rdev; this.blksize = blksize; this.ino = ino; this.size = size; this.blocks = blocks; this.atime = new Date(atim_msec); this.mtime = new Date(mtim_msec); this.ctime = new Date(ctim_msec); this.birthtime = new Date(birthtim_msec); }; // Create a C++ binding to the function which creates a Stats object. binding.FSInitialize(fs.Stats); fs.Stats.prototype._checkModeProperty = function(property) { return ((this.mode & constants.S_IFMT) === property); }; fs.Stats.prototype.isDirectory = function() { return this._checkModeProperty(constants.S_IFDIR); }; fs.Stats.prototype.isFile = function() { return this._checkModeProperty(constants.S_IFREG); }; fs.Stats.prototype.isBlockDevice = function() { return this._checkModeProperty(constants.S_IFBLK); }; fs.Stats.prototype.isCharacterDevice = function() { return this._checkModeProperty(constants.S_IFCHR); }; fs.Stats.prototype.isSymbolicLink = function() { return this._checkModeProperty(constants.S_IFLNK); }; fs.Stats.prototype.isFIFO = function() { return this._checkModeProperty(constants.S_IFIFO); }; fs.Stats.prototype.isSocket = function() { return this._checkModeProperty(constants.S_IFSOCK); }; // Don't allow mode to accidentally be overwritten. ['F_OK', 'R_OK', 'W_OK', 'X_OK'].forEach(function(key) { Object.defineProperty(fs, key, { enumerable: true, value: constants[key] || 0, writable: false }); });
通过Stats对象可以获取该文件的信息例如:文件大小、创建时间、文件类型等。
var fs = require('fs'); fs.stat('file_stats.js', function (err, stats) { if (!err){ console.log('stats: ' + JSON.stringify(stats, null, ' ')); console.log(stats.isFile() ? "Is a File" : "Is not a File"); console.log(stats.isDirectory() ? "Is a Folder" : "Is not a Folder"); console.log(stats.isSocket() ? "Is a Socket" : "Is not a Socket"); stats.isDirectory(); stats.isBlockDevice(); stats.isCharacterDevice(); //stats.isSymbolicLink(); //only lstat stats.isFIFO(); stats.isSocket(); } });
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe file_stats.js stats: { "dev": 1086025760, "mode": 33206, "nlink": 1, "uid": 0, "gid": 0, "rdev": 0, "ino": 12384898975555938, "size": 535, "atime": "2016-03-12T04:09:24.523Z", "mtime": "2014-11-10T22:12:29.000Z", "ctime": "2016-03-21T11:39:54.207Z", "birthtime": "2016-03-12T04:09:24.523Z" } Is a File Is not a Folder Is not a Socket Process finished with exit code 0
三、文件遍历
在其他系统也都有文件遍历.由于文件是树的形式存在,所以使用递归遍历.下面是用异步api,那同步api也能推出来。fs.readdirsync(path).
/** * Created by Administrator on 2016/3/22. */ var fs = require('fs'); var Path = require('path'); function WalkDirs(dirPath){ console.log(dirPath); fs.readdir(dirPath, function(err, entries){ for (var idx in entries){ var fullPath = Path.join(dirPath, entries[idx]); (function(fullPath){ fs.stat(fullPath, function (err, stats){ if (stats && stats.isFile()){ console.log(fullPath); } else if (stats && stats.isDirectory()){ WalkDirs(fullPath); } }); })(fullPath); } }); } WalkDirs("../");
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe file_readdir.js ../ ..\.idea ..\data ..\asyncReadWrite.js ..\Buffer.js ..\Immediate.js ..\Console.js ..\Interval.js ..\nexttick.txt ..\OpenClose.js ..\StreamReadWrite.js ..\syncReadWrite.js ..\nexttick1.txt ..\.idea\.name ..\.idea\encodings.xml ..\.idea\jsLibraryMappings.xml ..\.idea\misc.xml ..\.idea\modules.xml ..\.idea\NodeJsDemo.iml ..\.idea\workspace.xml ..\nexttick2.txt ..\data\config.txt ..\timer.js ..\SimpleReadWrite.js ..\data\file_readdir.js ..\data\grains.txt ..\data\fruit.txt ..\data\openColse1.txt ..\data\veggie.txt ..\data\openClose.txt Process finished with exit code 0
四、文件删除
根据前面的几个api,删除有fs.unlink(path,callback)那就有fs.unlink(path).
fs.unlink("../nexttick1.txt", function(err){ console.log(err ? "File Delete Failed" : "File Deleted"); });
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe file_readdir.js File Deleted Process finished with exit code 0
五、截断文件
截断文件把文件结束设置为比当前小的值来减少文件的大小.
fs.truncate = function(path, len, callback)
fs.truncateSync = function(path, len) 同步返回布尔值
fs.truncate("test.txt",8,function(err){ console.log(err?"File Truncate Failed":"File Truncated") })
六、建立删除文件夹
刚才是遍历用的是readdir,现在是建立则用fs.mkdir(path,[mode],callback)或fs.mkdirSync(path,[mode])。删除则用fs.rmdir(path,callback)或fs.rmdirSync(path).
fs.mkdir("../test",function(err){ console.log(err?"mkdir Failed":"mkdir success") if(!err) { rmdir(); } }); function rmdir() { fs.rmdir("../test",function(err){ console.log(err?"rmdir Failed":"rmdir success") }); }
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe file_readdir.js mkdir success rmdir success Process finished with exit code 0
七.文件重命名
这个重命名不只是改变文件的名字,它可以改变文件的路径。
fs.rename("test","../test1",function(err){ console.log(err ? "rename Failed" : "renamed"); })
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe file_readdir.js renamed Process finished with exit code 0
八、文件监视
文件发生变化时会执行回调函数.
fs.watchFile("../test1",{persistent:true,interval:5000},function(curr,prev){ console.log(curr.mtime); console.log(prev.mtime); }); fs.rename("../test1","test",function(err){ console.log(err ? "rename Failed" : "renamed"); })
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe file_readdir.js renamed Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间) Tue Mar 22 2016 19:30:11 GMT+0800 (中国标准时间)
persistent:持续 interval:时间间隔