fs.nodejs watchfilee 和 fs.watch 的区别

fs.watchFile
和 fs.watch 的区别 - CNode技术社区
卖过两年菜的程序员,现在主要研究前端架构。
他们俩个都是用来监视文件变动的(包括内容改动和名字、时间戳等的任何变化)
在官方文档两个方法都标注“Unstable”。
###watchFile()
相对稳定一些的是watchFile()这个方法,文档中介绍原理是轮询(每隔一個固定的时间去检查文件是否改动)。而且这个时间间隔是可以通过参数设置的。
###watch()
watch()这个方法是通过监听操作系统提供的各种“事件”(内核发布的消息)实现的。这个不同的平台实现的细节不一致,导致这个方法不能保证在所有平台上可用(而且经过实验发现在Mac上行为不正常,内容的改动只能触发一次回调,再改动watch()就没动静了)。
如果真正需要使用这个功能,优先试用watch(),如果在你的目标平台上无法正常使用,再考虑使用watchFile(),不过要小心千万不要用watchFile()监视太多文件,会导致内存暴涨。
另外,watch()在Mac上的问题,我找到了解决办法,稍后分享(在watch触发的回调中,隔1s重新调用FSWatcher的start方法)
如果不是及特殊需求,尽量使用现有的封装库,例如
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的Node.js中的文件系统-fs模块_美文阅读,精品文摘网
当前位置: &>&&>& >
Node.js中的文件系统-fs模块
标签(node): WebDevelop
在任何的系统中,与文件的交互都是非常重要的,特别是当配置参数写在一个文件中时,对文件系统的操作是必不可少的。在Node.js中同样也有专用的模块fs来处理与文件系统的交互。fs模块中,提供了与文件系统进行交互的良好的接口。就可以方便的对文件进行打开、读取、写人等操作。
同步与异步使用文件系统的差异
Node.js中的fs模块几乎所有的功能都会有两种形式可供选择:异步和同步。如读取文件的同步形式为readFileSync(path,[option],callba)和异步模式readFile(path,[option])。所以在编写代码时,理解这两种形式的不同是非常重要的。
同步方式的文件系统调用会导致阻塞,由于Node.js是单线程的,直到文件调用完成后,控制权才会被放回主线程,这也就导致了后台其他线程池中的很多线程不能够执行,从而导致Node.js中一定程度的性能问题。因此应该尽可能的减少使用同步方式的文件系统的方法调用。
异步调用会被主线程放置在事件队列中以备随后运行,这使得调用能够融入Node.js中的事件模型。但在执行代码时,就会变得有点棘手,因为事件并不能在预期的时候完成,这就需要有一个callback函数来规定当调用完成时需要完成的事。(这里可以去深入了解下Node.js的事件队列)
当然在大多数情况下,同步和异步文件系统调用的底层功能是一样的,只是实现的方式有区别。同步和异步文件系统调用都接受相同的参数,但是异步的方式都需要有一个额外的参数,即在调用完成时需要执行的回调函数。
总结一下:同步调用立刻执行,当执行完成后才会返回主线程进行对时间队列中事件的调用,而异步则是将该事件放入到事件队列中,实际的调用则是发生在它被事件循环提取时。
打开/关闭文件
一旦文件被打开,就可以读取文件中的内容或是往文件中写入文件,可以通过一个特定参数来设置。主要的方法为:
fs.open(path,flags,[mode],callback);
fs.openSync(path,flags,[mode]);
参数列表:
path: 用于指定文件系统的标准路径字符串。
flags: 用于指定打开文件的模式,读、写、追加等。
mode:用于设置文件访问模式,默认为0666,这表示可读可写。
打开文件用于读取,若文件不存在,则抛出异常
打开文件用于写操作,若文件不存在,则创建;若文件存在,则截断该文件(清空)
同w,但是若文件存在,则打开失败
打开文件用于追加,若不存在,则创建文件
同a,但若不存在,则打开失败
对于r w wx来说使得操作变为读写同时存在,对于a来说增加读取操作
文件开启后,若要关闭它迫使操作系统把更改应用到磁盘上,并释放操作系统锁,就需要调用以下方法来关闭一个打开的文件:
fs.close(fb,callback);
fs.closeSync(fb);
fb参数为一个文件的描述符,同步打开方式会将该描述符返回,而异步方式会放在回掉函数中:
//同步方式
var fd = fs.openSync('a.txt','w');
fs.closeSync(fd);
//异步方式
fs.open('a.txt','w',function(err,fd){
fs.close(fd);
文件的写入
文件的写入主要分成两种:简单文件写入和非简单写入,简单写入方式把一个字符串或是缓冲区(Buffer)的内容全部直接写入到一个文件中,而非简单写入方式可以指定数据的长度、起始位置等内容或是以流式方式写入。
简单文件写入
这是将一段数据写入文件的最简单方式。分为同步和异步两种形式:
fs.writeFile(path,data,[options],callback)
fs.writeFileSync(path,data,[options])
参数列表:
path:指定文件路径,可以是相对或是绝对路径。
data: 指定将要被写入到文件中的String或Buffer对象。
options:可以包含定义字符串编码,以及打开文件是使用的模式和标志的encoding、mode和flag属性。
callback:为异步方式专用。
简单实现的小例子
var fs = require('fs');
var config = {
maxFiles: 20,
maxConnections: 15,
rootPath: "/webroot"
var configTxt = JSON.stringify(config);
var options = {encoding:'utf8', flag:'w'};
fs.writeFile('../data/config.txt', configTxt, options, function(err){
console.log("Config Write Failed.");
console.log("Config Saved.");
//控制台输出
Config Saved.
非简单文件写入
非简单文件写入也分两种:面对String/Buffer(缓冲区的)和面对流的文件写入方式。
面对String/Buffer的写入方式同样也分同步和异步两种方式:
fs.writeSync(fd,data,offset,length,position);
fs.write(fd,data,offset,length,position,callback);
fd:为打开文件返回或是在callback参数中的文件描述符;
data:为将被写入到文件中的String/Buffer对象;
offset:指定data参数中开始索引的位置,如果想从当前索引开始,这个值就为null;
length:指定要写入的字节数,指定为null时表示一直写到末尾;
position:指定文件中的写入位置,指定为null时表示当前位置;
callback:只在异步中存在,可以接受两个参数error和bytes,bytes表示写入的字节数;
以下为同步写入文件:
var fs = require('fs');
var veggieTray = ['carrots', 'celery', 'olives'];
fd = fs.openSync('../data/veggie.txt', 'w');
while (veggieTray.length){
veggie = veggieTray.pop() + " ";
var bytes = fs.writeSync(fd, veggie, null, null);
console.log("Wrote %s %dbytes", veggie, bytes);
fs.closeSync(fd);
//控制台显示
Wrote olives 7bytes
Wrote celery 7bytes
Wrote carrots 8bytes
异步写入方式:
var fs = require('fs');
var fruitBowl = ['apple', 'orange', 'banana', 'grapes'];
function writeFruit(fd){
if (fruitBowl.length){
var fruit = fruitBowl.pop() + " ";
fs.write(fd, fruit, null, null, function(err, bytes){
console.log("File Write Failed.");
console.log("Wrote: %s %dbytes", fruit, bytes);
writeFruit(fd);
fs.close(fd);
fs.open('../data/fruit.txt', 'w', function(err, fd){
writeFruit(fd);
//控制台显示
Wrote: grapes 7bytes
Wrote: banana 7bytes
Wrote: orange 7bytes
Wrote: apple 6bytes
面对流的文件写入
往一个文件中写入大量数据,最好的方法就是使用流,把文件作为一个Writable打开,就可以往里面写数据,或是使用pipe()方法,将一个Readable流链接到Writable上,这样就很容易写来自源Readable流(如HTTP请求)的数据了;
使用以下方法创建一个Writable流:
fs.createWriteStream(path,[options]);
参数列表:
path:指定文件的路径,可以是相对或是绝对路径;
options:定义字符串编码以及打开文件时使用的模式和标志的encoding、mode、和flag属性
一旦打开了Writable文件流,就可以使用标准的流式write(buffer)方法来使用,写入完成后,再调用end();
一个简单的小例子
var fs = require('fs');
var grains = ['wheat', 'rice', 'oats'];
var options = { encoding: 'utf8', flag: 'w' };
var fileWriteStream = fs.createWriteStream("../data/grains.txt", options);
fileWriteStream.on("close", function(){
console.log("File Closed.");
while (grains.length){
var data = grains.pop() + " ";
fileWriteStream.write(data);
console.log("Wrote: %s", data);
fileWriteStream.end();
//控制台输出
Wrote: oats
Wrote: rice
Wrote: wheat
File Closed.
涉及的方法,以及方式都和文件的写入差不多,主要的方法有:
fs.readFile(path,[options],callback);
fs.readFildSync(path,[options]);
非简单读取
fs.read(fd,buffer,offset,length,position,callback);
fs.readSync(fd,buffer,offset,length,position);
fs.createReadStream(path,[options]);
fs模块的其他方法
验证文件/目录路径的存在性
fs.exists(path,callback);
fs.existsSync(path);
注: 同步方法返回true/false,异步方法callback仅仅只有一个err对象表示是否删除成功。
获取文件信息
fs.stats(path,callback);
fs.statsSync(path);
注: 方法返回或在回掉中放置一个Status对象,该对象下有一些列的方法和属性如下:
如果是一个文件,则返回true
isDirectory()
如果是一个目录,则返回true
isSocket()
如果是一个套接字,则返回true
文件所在设备的ID
文件的访问模式
文件的字节数
存储该文件的块大小,以字节为单位
文件在磁盘上占用的块的数目
上次访问文件的时间
文件的最后修改时间
文件的创建时间
简单的小例子:
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();
"mode": 33206,
"nlink": 1,
"rdev": 0,
"ino": 8288,
"size": 535,
"atime": "T04:03:18.481Z",
"mtime": "T22:12:29.000Z",
"ctime": "T04:03:18.504Z",
"birthtime": "T04:03:18.481Z"
Is not a Folder
Is not a Socket
fs.readdir(path,callback);
fs.readdirSync(path);
注: 方法返回或在回掉中放置一个在指定路径条目名字的字符串数组
一个深度遍历文件夹内容的例子:
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("../admin");
fs.unlink(path,callback);
fs.unlinkSync(path);
注: 同步方法返回true/false,异步方法callback仅仅只有一个err对象表示是否删除成功。
建立/删除目录
fs.mkdir(path,[mode],callback);
fs.mkdirSync(path,[mode]);
fs.rmdir(path,[mode],callback);
fs.rmdirSync(path,[mode]);
注: 同步方法返回true/false,异步方法callback仅仅只有一个err对象表示是否建立/删除成功。无论哪个方法都只能删除/建立一级目录。
重命名文件/目录
fs.rename(oldPath,newPath,callback);
fs.renameSync(oldPath,newPath);
注: 同步方法返回true/false,异步方法callback仅仅只有一个err对象表示是否重命名成功。
截断(清空)文件
截断文件是指通过把文件结束处设置为比当前值小赖减小文件大小。对于文件两不断增长的文件使用截断就会有良好的效果。
fs.truncate(path,len,callback);
fs.truncateSync(path,len);
注: 同步方法返回true/false,异步方法callback仅仅只有一个err对象表示是否截断成功。
监视文件更改
如果你希望在文件发生改动时,做一些事情。这个方法就是为了应对这种场景。
fs.watchFile(path,[options],callback);
options参数包含persistent(持续)和interval属性。如果文件被监视,就运行这个程序,persistent就为true。interval属性指定文件更改触发的间隔时间。callback会附带两个Status对象,分别表示现在和之前的状态。
每隔5秒监视一个名为log.txt的文件,并使用Status对象来输出本次和上次被修改的时间。
fs.watchFile('log.txt',{persistent:true,interval:5000},function(curr,prev){
console.log('log.txt modified at: ' + curr.mtime);
console.log('Previous modification was: ' + prev.mtime);
小结:Node.js中的fs模块差不多就这些内容了,主要实现了与文件系统交互的能力,使得Node.js更好的使用文件。
延伸阅读:
(责任编辑:美朵)
每日重点推荐
夏医生是自己多年老同事的儿子,国外学成归来做事业,老同事担心儿子诊所刚开,门厅罗雀伤了自尊,便偷偷塞钱给李梅,求她装病去“捧场”。
04-05 12-15 12-15
一周热点文章
在线阅读专题node.js中watch机制详解
投稿:hebedich
字体:[ ] 类型:转载 时间:
本文给大家带来的是一篇关于nodejs中watch机制的探讨,主要探讨内容是为什么watch不是银弹,尝试使用更好的方案来解决这个问题
几乎所有构建系统都选择使用watch机制来解决开发过程中需要反复生成构建后文件的问题,但在watch机制下,长期以来我们必须忍受修改完代码,保存完代码必须喝口茶才能刷新看看效果的问题。在这里我们尝试探讨为什么watch不是银弹,并尝试寻找一种更好的方案来解决这个问题。
watch基于的事实
当一个文件修改,我们能知道其修改可能导致的文件修改,那么重新构建这些文件即可。
通常对于文件A,构建成文件B这种场景,这种对应关系是极好确定的。但现实场景下,构建过程往往不是那么简单。例如:
文件A + 文件B(被文件A引用) -& 文件C
在这种场景下,文件B的修改,可能难以定位哪些文件需要重新跑构建任务,因为可能有很多文件引用了文件B。
除非我们建立一个依赖树,并在每次文件更新的情况下更新依赖树,并根据新的依赖树触发文件构建。但这对每一个插件都需要自行实现这个机制,并且极易出错。故实际上watch机制仅仅是重跑了整个task。所以当项目越来越大的时候,watch机制将越来越慢(因为越来越多文件需要重新跑整个过程,即使通过缓存减少了整个过程所需的耗时)。
src直接可用
AlloyTeam & @ldjking,简单来说直接让src直接可跑,把构建任务放置在浏览器端,甚至根本不构建,既可做到及时修改及时刷新,在开发过程中减少了时间消耗。线下构建仅仅负责性能优化上的问题,不负责开发效率。
典型代表有LESS、React等。但也有一些问题:
难以在浏览器端实现优雅的构建方式,难以提供强大的功能进一步减少开发成本,大部分只能采用类似&style type="text/less"&&/style&的方式引入脚本。
开发模式下的执行顺序不一定和实际场景相同,可能导致隐形bug出现,例如实现一个HTML inline由于开发模式下inline是异步的,而发布模式下inline时同步的,产生莫名其妙的bug。
浏览器编译性能堪忧,例如js版的sass,编译速度几乎无法忍受。
需要维护线上、线下两套构建系统,增加了工具开发成本。
本地服务器动态构建
一个事实是:在合理的规范支持下,我们可以从浏览器请求的文件,回溯到该文件构建过程中的入口文件。这样我们就可以动态触发一次构建过程。
通过在本地建立一个服务器,让服务器捕获请求后,在服务器中动态构建。只要回溯到入口文件,我们便能将入口文件丢进gulp插件组成的管道中,则输出便是浏览器需要的文件。
这样我们就能解决上面的所有问题。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具热门装机教程
您现在的位置: &>&
Linux下gulp报错Error:watch ENOSPC如何解决
来源: & &发布时间: 10:35:59
  用户反映在Fedora和Ubuntu的操作系统中,使用gulp时出现问题,gulp报错Error:watch&ENOSPC的问题,出现这样的问题是怎么回事呢?还有就是Linux下gulp报错Error:watch&ENOSPC我们又该怎样进行解决呢?下面就一起来看看具体的操作方法吧!
  用gulp启动,错误如下:
  Error:&watch&ENOSPC
  at&exports._errnoException&(util.js:746:11)
  at&FSWatcher.start&(fs.js:1172:11)
  at&Object.fs.watch&(fs.js:1198:11)
  at&Gaze._watchDir&(/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:289:30)
  at&/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:358:10
  at&iterate&(/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/helper.js:52:5)
  at&Object.forEachSeries&(/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/helper.js:66:3)
  at&Gaze._initWatched&(/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:354:10)
  at&Gaze.add&(/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:177:8)
  at&new&Gaze&(/home/ajaxGu/work/froad/anhui-standard/personal-h5/node_modules/gulp/node_modules/vinyl-fs/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js:74:10)
  解决方案:
  当前问题主要是因为gulp的watch需要监听很多文件的改动,但是fedora、ubuntu系统的文件句柄其实是有限制的,因此可以使用以下命令:
  echo&fs.inotify.max_user_watches=524288&|&sudo&tee&-a&/etc/sysctl.conf&&&&sudo&sysctl&-p
  对于以上Linux下gulp报错Error:watch&ENOSPC的解决方法就介绍完了,如果用户也出现以上同样问题,那么可以按照操作方法赶紧试试解决吧!
[上一个]:
[下一个]:node.js之fs模块 - 简书
node.js之fs模块
Node.js的文件系统的Api
//公共引用
var fs = require('fs'),
path = require('path');
1、读取文件readFile函数
//readFile(filename,[options],callback);
* filename, 必选参数,文件名
* [options],可选参数,可指定flag(文件操作选项,如r+ 读写;w+ 读写,文件不存在则创建)及encoding属性
* callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据
fs.readFile(__dirname + '/test.txt', {flag: 'r+', encoding: 'utf8'}, function (err, data) {
console.error(err);
console.log(data);
// fs.writeFile(filename,data,[options],callback);
var w_data = '这是一段通过fs.writeFile函数写入的内容;\r\n';
var w_data = new Buffer(w_data);
* filename, 必选参数,文件名
* data, 写入的数据,可以字符或一个Buffer对象
* [options],flag,mode(权限),encoding
* callback 读取文件后的回调函数,参数默认第一个err,第二个data 数据
fs.writeFile(__dirname + '/test.txt', w_data, {flag: 'a'}, function (err) {
console.error(err);
console.log('写入成功');
3、以追加方式写文件
// fs.appendFile(filename,data,[options],callback);
fs.appendFile(__dirname + '/test.txt', '使用fs.appendFile追加文件内容', function () {
console.log('追加内容完成');
4、打开文件
// fs.open(filename, flags, [mode], callback);
* filename, 必选参数,文件名
* flags, 操作标识,如"r",读方式打开
* [mode],权限,如777,表示任何用户读写可执行
* callback 打开文件后回调函数,参数默认第一个err,第二个fd为一个整数,表示打开文件返回的文件描述符,window中又称文件句柄
fs.open(__dirname + '/test.txt', 'r', '0666', function (err, fd) {
console.log(fd);
5、读文件,读取打开的文件内容到缓冲区中;
//fs.read(fd, buffer, offset, length, position, callback);
* fd, 使用fs.open打开成功后返回的文件描述符
* buffer, 一个Buffer对象,v8引擎分配的一段内存
* offset, 整数,向缓存区中写入时的初始位置,以字节为单位
* length, 整数,读取文件的长度
* position, 整数,读取文件初始位置;文件大小以字节为单位
* callback(err, bytesRead, buffer), 读取执行完成后回调函数,bytesRead实际读取字节数,被读取的缓存区对象
fs.open(__dirname + '/test.txt', 'r', function (err, fd) {
console.error(err);
var buffer = new Buffer(255);
console.log(buffer.length);
//每一个汉字utf8编码是3个字节,英文是1个字节
fs.read(fd, buffer, 0, 9, 3, function (err, bytesRead, buffer) {
console.log(bytesRead);
console.log(buffer.slice(0, bytesRead).toString());
//读取完后,再使用fd读取时,基点是基于上次读取位置计算;
fs.read(fd, buffer, 0, 9, null, function (err, bytesRead, buffer) {
console.log(bytesRead);
console.log(buffer.slice(0, bytesRead).toString());
6、写文件,将缓冲区内数据写入使用fs.open打开的文件
//fs.write(fd, buffer, offset, length, position, callback);
* fd, 使用fs.open打开成功后返回的文件描述符
* buffer, 一个Buffer对象,v8引擎分配的一段内存
* offset, 整数,从缓存区中读取时的初始位置,以字节为单位
* length, 整数,从缓存区中读取数据的字节数
* position, 整数,写入文件初始位置;
* callback(err, written, buffer), 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象
fs.open(__dirname + '/test.txt', 'a', function (err, fd) {
console.error(err);
var buffer = new Buffer('写入文件数据内容');
//写入'入文件'三个字
fs.write(fd, buffer, 3, 9, 12, function (err, written, buffer) {
console.log('写入文件失败');
console.error(err);
console.log(buffer.toString());
//写入'数据内'三个字
fs.write(fd, buffer, 12, 9, null, function (err, written, buffer) {
console.log(buffer.toString());
7、刷新缓存区;
// 使用fs.write写入文件时,操作系统是将数据读到内存,再把数据写入到文件中,当数据读完时并不代表数据已经写完,因为有一部分还可能在内在缓冲区内。
// 因此可以使用fs.fsync方法将内存中数据写入文件;--刷新内存缓冲区;
//fs.fsync(fd, [callback])
* fd, 使用fs.open打开成功后返回的文件描述符
* [callback(err, written, buffer)], 写入操作执行完成后回调函数,written实际写入字节数,buffer被读取的缓存区对象
fs.open(__dirname + '/test.txt', 'a', function (err, fd) {
var buffer = new Buffer('我爱nodejs编程');
fs.write(fd, buffer, 0, 9, 0, function (err, written, buffer) {
console.log(written.toString());
fs.write(fd, buffer, 9, buffer.length - 9, null, function (err, written) {
console.log(written.toString());
fs.fsync(fd);
fs.close(fd);
8、创建目录;
//使用fs.mkdir创建目录
//fs.mkdir(path, [mode], callback);
* path, 被创建目录的完整路径及目录名;
* [mode], 目录权限,默认0777
* [callback(err)], 创建完目录回调函数,err错误对象
fs.mkdir(__dirname + '/fsDir', function (err) {
console.log('创建目录成功')
9、读取目录;
//使用fs.readdir读取目录,重点其回调函数中files对象
//fs.readdir(path, callback);
* path, 要读取目录的完整路径及目录名;
* [callback(err, files)], 读完目录回调函数;err错误对象,files数组,存放读取到的目录中的所有文件名
fs.readdir(__dirname + '/fsDir/', function (err, files) {
console.error(err);
files.forEach(function (file) {
var filePath = path.normalize(__dirname + '/fsDir/' + file);
fs.stat(filePath, function (err, stat) {
if(stat.isFile()) {
console.log(filePath + ' is: ' + 'file');
if(stat.isDirectory()) {
console.log(filePath + ' is: ' + 'dir');
for (var i = 0; i & files. i++) {
//使用闭包无法保证读取文件的顺序与数组中保存的致
(function () {
var filePath = path.normalize(__dirname + '/fsDir/' + files[i]);
fs.stat(filePath, function (err, stat) {
if(stat.isFile()) {
console.log(filePath + ' is: ' + 'file');
if(stat.isDirectory()) {
console.log(filePath + ' is: ' + 'dir');
10、查看文件与目录的信息;
//fs.stat(path, callback);
//fs.lstat(path, callback); //查看符号链接文件
* path, 要查看目录/文件的完整路径及名;
* [callback(err, stats)], 操作完成回调函数;err错误对象,stat fs.Stat一个对象实例,提供如:isFile, isDirectory,isBlockDevice等方法及size,ctime,mtime等属性
//实例,查看fs.readdir
11、查看文件与目录的是否存在
//fs.exists(path, callback);
* path, 要查看目录/文件的完整路径及名;
* [callback(exists)], 操作完成回调函数;exists true存在,false表示不存在
fs.exists(__dirname + '/te', function (exists) {
var retTxt = exists ? retTxt = '文件存在' : '文件不存在';
console.log(retTxt);
12、修改文件访问时间与修改时间
//fs.utimes(path, atime, mtime, callback);
* path, 要查看目录/文件的完整路径及名;
* atime, 新的访问时间
* ctime, 新的修改时间
* [callback(err)], 操作完成回调函数;err操作失败对象
fs.utimes(__dirname + '/test.txt', new Date(), new Date(), function (err) {
console.error(err);
fs.stat(__dirname + '/test.txt', function (err, stat) {
console.log('访问时间: ' + stat.atime.toString() + '; \n修改时间:' + stat.mtime);
console.log(stat.mode);
13、修改文件或目录的操作权限
//fs.utimes(path, mode, callback);
* path, 要查看目录/文件的完整路径及名;
* mode, 指定权限,如:0666 8进制,权限:所有用户可读、写,
* [callback(err)], 操作完成回调函数;err操作失败对象
fs.chmod(__dirname + '/fsDir', 0666, function (err) {
console.error(err);
console.log('修改权限成功')
14、移动/重命名文件或目录
//fs.rename(oldPath, newPath, callback);
* oldPath, 原目录/文件的完整路径及名;
* newPath, 新目录/文件的完整路径及名;如果新路径与原路径相同,而只文件名不同,则是重命名
* [callback(err)], 操作完成回调函数;err操作失败对象
fs.rename(__dirname + '/test', __dirname + '/fsDir', function (err) {
console.error(err);
console.log('重命名成功')
15、删除空目录
//fs.rmdir(path, callback);
* path, 目录的完整路径及目录名;
* [callback(err)], 操作完成回调函数;err操作失败对象
fs.rmdir(__dirname + '/test', function (err) {
fs.mkdir(__dirname + '/test', 0666, function (err) {
console.log('创建test目录');
console.log('删除空目录失败,可能原因:1、目录不存在,2、目录不为空')
console.error(err);
console.log('删除空目录成功!');
16、监视文件
//对文件进行监视,并且在监视到文件被修改时执行处理
//fs.watchFile(filename, [options], listener);
* filename, 完整路径及文件名;
* [options], persistent true表示持续监视,不退出程序;interval 单位毫秒,表示每隔多少毫秒监视一次文件
* listener, 文件发生变化时回调,有两个参数:curr为一个fs.Stat对象,被修改后文件,prev,一个fs.Stat对象,表示修改前对象
fs.watchFile(__dirname + '/test.txt', {interval: 20}, function (curr, prev) {
if(Date.parse(prev.ctime) == 0) {
console.log('文件被创建!');
} else if(Date.parse(curr.ctime) == 0) {
console.log('文件被删除!')
} else if(Date.parse(curr.mtime) != Date.parse(prev.mtime)) {
console.log('文件有修改');
fs.watchFile(__dirname + '/test.txt', function (curr, prev) {
console.log('这是第二个watch,监视到文件有修改');
17、取消监视文件
//取消对文件进行监视
//fs.unwatchFile(filename, [listener]);
* filename, 完整路径及文件名;
* [listener], 要取消的监听器事件,如果不指定,则取消所有监听处理事件
var listener = function (curr, prev) {
console.log('我是监视函数')
fs.unwatchFile(__dirname + '/test.txt', listener);
18、监视文件或目录
// 对文件或目录进行监视,并且在监视到修改时执行处理;
// fs.watch返回一个fs.FSWatcher对象,拥有一个close方法,用于停止watch操作;
// 当fs.watch有文件变化时,会触发fs.FSWatcher对象的change(err, filename)事件,err错误对象,filename发生变化的文件名
// fs.watch(filename, [options], [listener]);
* filename, 完整路径及文件名或目录名;
* [listener(event, filename], 监听器事件,有两个参数:event 为rename表示指定的文件或目录中有重命名、删除或移动操作或change表示有修改,filename表示发生变化的文件路径
var fsWatcher = fs.watch(__dirname + '/test', function (event, filename) {
//console.log(event)
//console.log(fsWatcher instanceof FSWatcher);
fsWatcher.on('change', function (event, filename) {
console.log(filename + ' 发生变化')
//30秒后关闭监视
setTimeout(function () {
console.log('关闭')
fsWatcher.close(function (err) {
console.error(err)
console.log('关闭watch')
}, 30000);
19、文件流
* 流,在应用程序中表示一组有序的、有起点有终点的字节数据的传输手段;
* Node.js中实现了stream.Readable/stream.Writeable接口的对象进行流数据读写;以上接口都继承自EventEmitter类,因此在读/写流不同状态时,触发不同事件;
* 关于流读取:Node.js不断将文件一小块内容读入缓冲区,再从缓冲区中读取内容;
* 关于流写入:Node.js不断将流数据写入内在缓冲区,待缓冲区满后再将缓冲区写入到文件中;重复上面操作直到要写入内容写写完;
* readFile、read、writeFile、write都是将整个文件放入内存而再操作,而则是文件一部分数据一部分数据操作;
* -----------------------流读取-------------------------------------
* 读取数据对象:
* fs.ReadStream 读取文件
* http.IncomingMessage 客户端请求或服务器端响应
* net.Socket
Socket端口对象
* child.stdout
子进程标准输出
* child.stdin
子进程标准入
* process.stdin 用于创建进程标准输入流
* Gzip、Deflate、DeflateRaw
* 触发事件:
* readable
数据可读时
数据读取后
数据读取完成时
数据读取错误时
关闭流对象时
* 读取数据的对象操作方法:
读取数据方法
* setEncoding
设置读取数据的编
通知对象众目停止触发data事件
通知对象恢复触发data事件
设置数据通道,将读入流数据接入写入流;
当流数据绑定一个解析器时,此方法取消解析器
* ------------------------流写入-------------------------------------
* 写数据对象:
* fs.WriteStream
写入文件对象
* http.clientRequest
写入HTTP客户端请求数据
* http.ServerResponse
写入HTTP服务器端响应数据
* net.Socket
读写TCP流或UNIX流,需要connection事件传递给用户
* child.stdout
子进程标准输出
* child.stdin
子进程标准入
* Gzip、Deflate、DeflateRaw
* 写入数据触发事件:
当write方法返回false时,表示缓存区中已经输出到目标对象中,可以继续写入数据到缓存区
当end方法调用,全部数据写入完成
当用于读取数据的对象的pipe方法被调用时
当unpipe方法被调用
当发生错误
* 写入数据方法:
用于写入数据
结束写入,之后再写入会报错;
20、创建读取流
//fs.createReadStream(path, [options])
* path 文件路径
* [options] flags:指定文件操作,默认'r',读操作;encoding,指定读取流编码;autoClose, 是否读取完成后自动关闭,默认true;start指定文件开始读取位置;end指定文件开始读结束位置
var rs = fs.createReadStream(__dirname + '/test.txt', {start: 0, end: 2});
//open是ReadStream对象中表示文件打开时事件,
rs.on('open', function (fd) {
console.log('开始读取文件');
rs.on('data', function (data) {
console.log(data.toString());
rs.on('end', function () {
console.log('读取文件结束')
rs.on('close', function () {
console.log('文件关闭');
rs.on('error', function (err) {
console.error(err);
//暂停和回复文件读取;
rs.on('open', function () {
console.log('开始读取文件');
rs.pause();
rs.on('data', function (data) {
console.log(data.toString());
setTimeout(function () {
rs.resume();
21、创建写入流
//fs.createWriteStream(path, [options])
* path 文件路径
* [options] flags:指定文件操作,默认'w',;encoding,指定读取流编码;start指定写入文件的位置
/* ws.write(chunk, [encoding], [callback]);
可以为Buffer对象或一个字符串,要写入的数据
* [encoding],
* [callback],
写入后回调
/* ws.end([chunk], [encoding], [callback]);
* [chunk],
要写入的数据
* [encoding],
* [callback],
写入后回调
var ws = fs.createWriteStream(__dirname + '/test.txt', {start: 0});
var buffer = new Buffer('我也喜欢你');
ws.write(buffer, 'utf8', function (err, buffer) {
console.log(arguments);
console.log('写入完成,回调函数没有参数')
//最后再写入的内容
ws.end('再见');
//使用流完成复制文件操作
var rs = fs.createReadStream(__dirname + '/test.txt')
var ws = fs.createWriteStream(__dirname + '/test/test.txt');
rs.on('data', function (data) {
ws.write(data)
ws.on('open', function (fd) {
console.log('要写入的数据文件已经打开,文件描述符是: ' + fd);
rs.on('end', function () {
console.log('文件读取完成');
ws.end('完成', function () {
console.log('文件全部写入完成')
//关于WriteStream对象的write方法返回一个布尔类型,当缓存区中数据全部写满时,返回
//表示缓存区写满,并将立即输出到目标对象中
//第一个例子
var ws = fs.createWriteStream(__dirname + '/test/test.txt');
for (var i = 0; i & 10000; i++) {
var w_flag = ws.write(i.toString());
//当缓存区写满时,输出false
console.log(w_flag);
//第二个例子
var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');
var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');
rs.on('data', function (data) {
var flag = ws.write(data);
console.log(flag);
//系统缓存区数据已经全部输出触发drain事件
ws.on('drain', function () {
console.log('系统缓存区数据已经全部输出。')
22、管道pipe实现流读写
//rs.pipe(destination, [options]);
* destination 必须一个可写入流数据对象
* [opations] end 默认为true,表示读取完成立即关闭文件;
var rs = fs.createReadStream(__dirname + '/test/Until You.mp3');
var ws = fs.createWriteStream(__dirname + '/test/untiyou.mp3');
rs.pipe(ws);
rs.on('data', function (data) {
console.log('数据可读')
rs.on('end', function () {
console.log('文件读取完成');
//ws.end('再见')
看这里就好了
首页的子矜就是我了。

我要回帖

更多关于 fs.watchfile 的文章

 

随机推荐