Node.js API实例讲解——FS文件操作
FS文件操作
写文件
写文件的意思感觉是写一个文件,准确来说,这里的写文件是把数据写入到一个文件中,当文件不存在时会创建一个文件。那么细化来看,过程应该是先打开一个文件,如果文件不存在就创建一个新的文件,然后把数据写入这个文件。
打开文件使用fs.open方法,写入数据使用fs.write方法,先做个例子。
var fs = require("fs"); fs.open("new.txt","w",function(err,fd){ var buf = new Buffer("你好啊"); fs.write(fd,buf,0,buf.length,0,function(err,written,buffer){}); })
首先打开文件new.txt,然后写入“你好啊”数据。说起来容易,同时发现这里有很多参数。下面将详细介绍open和write方法。
fs.open(path, flags, callback)
fs.openSync(path,flags) 是同步方法,return fd,如果有错误直接throw抛出错误。
path 参数,表示要打开文件的路径,flags标志参数,它限制打开的文件是可读、可写或可读写等方式,callback(err,fd)回调方法中fd表示打开文件的文件描述符。这里不好理解的是flags标志参数。
flags 参数可使用标志:
"r" 表示,打开文件进行读取。如果该文件不存在,将发生异常。
"r+" 表示,打开文件进行读取和写入。如果该文件不存在,将发生异常。
"rs" 与 "r" 一样,但采用同步方式,这个方式很消耗性能,一般情况下不会用到。
"rs+" 与 "r+" 一样,但采用同步方式,这个方式很消耗性能,一般情况下不会用到。
"w" 表示,打开文件进行写入。如果文件不存在会创建一个文件,这种写入方式会全部删除旧有的数据,然后再写入数据。
"w+" 表示,打开文件进行读取和写入。如果文件不存在会创建一个文件,这种写入方式会全部删除旧有的数据,然后再写入数据。
"wx" 和 "w" 相同,不同的是它是独占模式。
"wx+" 和 "w+" 相同,不同的是它是独占模式。
"a" 表示,打开文件进行追加,如果文件不存在会创建一个文件,这个模式不同于"w",它不会删除旧有的数据,而是会在后面追加数据。
"a+" 表示,打开文件进行追加和读取,如果文件不存在会创建一个文件,这个模式不同于"w",它不会删除旧有的数据,而是会在后面追加数据。
"ax" 和 "a" 相同,不同的是它是独占模式。
"ax+" 和 "ax" 相同,不同的是它是独占模式。
OK!看起来好多,还是做一些例子吧。
var fs = require("fs"); fs.open("new.txt","r",function(err,fd){ var buf = new Buffer("你好啊"); var c = fs.writeSync(fd,buf,0,buf.length,0); console.log(c) })
上面的例子,只是把"w"改成"r",前提是new.txt文件存在,运行后,会出现错误提示,大概意思是无权写入。
Error: EPERM, operation not permitted
原因不言而喻,"r"表示只能被读,而不能写入。
下面这个例子用于说明"a"追加 和 "w"写入模式的差异,这个例子前提是,有一个已存在的new.txt文件,文件内有“你好啊”数据。
"w"模式
var fs = require("fs"); fs.open("new.txt","w",function(err,fd){ var buf = new Buffer("1234"); fs.writeSync(fd,buf,0,buf.length,0); })
运行后,打开new.txt内容是“1234”而旧有的数据消失了。
我们在把new.txt文件内容改成“你好啊”,然后把"w"改成"a",运行!
var fs = require("fs"); fs.open("new.txt","a",function(err,fd){ var buf = new Buffer("1234"); fs.writeSync(fd,buf,0,buf.length,0); })
运行后,打开文件new.txt文件,内容是“你好啊1234”。
fs.write(fd, buffer, offset, length, position, callback)
fs.writeSync(fd, buffer, offset, length, position) 方法是同步写入,它返回写入多少bytes数量。
fd参数,文件描述符,通过fs.open得到。
buffer参数,是要写入的数据,Buffer对象,buffer尺寸的大小设置最好是8的倍数,效率较高。
yellowoffset参数,要写入buffer的起始位置。
length参数,要写入buffer的长度。通过offset和length规定buffer中那些数据应该被写入到文件。
position参数,写入到文件的什么位置。
callback((err, written, buffer)回调方法,当出现异常会抛出err,written是写入了多少bytes,buffer写入的数据。
fs.open 打开了文件,当然使用后应该关闭close文件,通过fs.close(fd, callback)和fs.closeSync(fd)方法可以关闭打开的文件,这个方法比较简单,不再多说。
上面写入方法是通过open得到fd(文件描述符)然后再写入文件的方式,其实还有其他方法。
fs.writeFile(filename, data, [options], callback)
fs.writeFileSync(filename, data, [options]) 同步方式。
filename String类型, 文件名称。
data String | Buffer类型,要写入的数据。
options[可选] Objectl 类型,默认值 {encoding:"utf8",flag:"w"}
callback(err) 回调函数
var fs = require("fs"); fs.writeFile("myfile.txt","Javascript很赞",function(err){ if(!err) console.log("写入成功!") })
fs.appendFile(filename, data, [options], callback)
fs.appendFileSync(filename, data, [options]) 同步方式。
参看 fs.writeFile 方法,差别就是 [options]的flag默认值是"a",所以它以追加方式写入数据。
读文件
有了前面的写文件,读文件就好办多了,还是老规矩,先写代码再做说明,但这次结合之前学到的,开发一个判断文件是否是png格式图片文件的程序。
假设当前目录下有个1.png文件,我们来判断这个文件是png图片。
var fs = require("fs"); fs.open("1.png","r",function(err,fd){ // PNG头部 8 bytes是固定的,来判断文件前8bytes。 var header = new Buffer([137,80,78,71,13,10,26,10]); var buf = new Buffer(8); fs.read(fd,buf,0,buf.length,0,function(err,bytesRead,buffer){ if(header.toString() === buffer.toString()){ console.log("是PNG格式图片文件"); } }) })
分析这个程序,先是用fs.open打开1.png文件,然后header数据是PNG图片标识数据,位于PNG图片前8个bytes,只要读取1.png文件前8bytes数据,然后对比一下数据是否一致就可以了。
fs.read(fd, buffer, offset, length, position, callback)
fs.read(fd, buffer, offset, length, position) 方法是同步写入,它返回读取了多少bytes数量。
fd参数,文件描述符,通过fs.open得到。
buffer参数,是把读取的数据写入这个对象,是个Buffer对象。
offset参数,写入buffer的起始位置。
length参数,写入buffer的长度。
position参数,文件的什么位置开始读。
callback(err,bytesRead, buffer)回调方法,当出现异常会抛出err,bytesRead是读取了多少bytes,buffer读取到的数据。
和写文件同样的,除了fs.read方式读取文件外,还有一个读取文件的方式。
fs.readFile(filename, [options], callback)
fs.readFileSync(filename,[options]) 同步方式,retur读取到的数据。
filename String类型,表示要读取的文件名
options[可选] Object类型,默认值是 {encoding:null,flag:"r"}
callback(err,data) 回调函数,data表示读取的数据。
例
var fs = require("fs"); var data = fs.readFileSync("myfile.txt"); console.log(data.toString());
小结一下
读取和写入都有两种不同方式,一个是先open,然后操作读写,但需要手工调用fs.close关闭文件,这种方式适合于多次写入或读取。还有一次性服务的,writeFile/appendFile/readFile方法只是写入或读取一次,内部自动调用了fs.close方法。
上面两个小节内容稍微多了一点,以下几节内容相对轻松了,现在可以稍微休息一下。
截断文件
截断文件,说白了就是把整个文件内容删除了,然后再加入new Buffer(len)的空数据,这个方法多数情况没什么用。以下是方法。
fs.ftruncate(fd, len, callback)
fs.ftruncateSync(fd, len)
fs.truncate(path, len, callback)
fs.truncateSync(path, len)
这些方法很简单,做个例子说明一下。
var fs = require("fs"); fs.open("myfile.txt","w",function(err,fd){ fs.ftruncate(fd,5,function(err){ console.log(err) }) })
fs.truncateSync("myfile.txt",5);
文件链接
文件链接在“文件系统概述”中用官方口气介绍了一次。但通俗点更好理解,说白了就是为一个文件创建一个特殊的链接,这个链接看起来像是一个文件,和快捷方式很像,这样理解就可了,熟悉linux ln命令的对文件链接会很熟悉这个概念。
还是先做实例,再说明。
var fs = require("fs"); fs.linkSync("file.txt","filelink.txt");
var fs = require("fs"); fs.link("file.txt","filelink.txt",function(err){ console.log(err); });
上面代码是为file.txt文件创建个“链接文件”filelink.txt,创建成功后,如果更改其中任何一个文件,相应的那个文件都会改变。
更改文件的查看和更新时间
这个很好理解,查看文件属性时,会看到文件的创建事件、更改时间、查看事件。看以下代码。
var fs = require("fs"); fs.utimes( "file.txt", new Date("1982-2-2"), new Date("1988-5-5"), function(err){} );
上面代码的意思是,把file.txt文件的查看时间改成1982/2/2,最新更改时间改成1988/5/5。
fs.utimes(path, atime, mtime, callback)
fs.utimesSync(path, atime, mtime) 同步方式
path:String 更改的文件名字路径。
atime:Date 查看时间。
mtime:Date 更改时间。
callback(err) 回调函数。
fs.futimes(fd, atime, mtime, callback)
fs.futimesSync(fd, atime, mtime)
和utimes方法一样,只不过第一个参数是 fd 文件描述符。
监听文件
参看:“文件夹操作”一节。
在“文件夹操作”一节介绍了一种监听方式,下面还有一种专门监听文件的方法。
fs.watchFile(filename, [options], listener)
这个方法添加文件更改监听器。
filename:String 要监听的文件名。
options[可选]:Object,默认值是{ persistent: true, interval: 5007 } , persistent表示是否持久运作,这个意思是,true的时候当前process进程不会退出,如果是false,就不会阻止当前进程退出,不过可以使用 setInterval 方法模拟 persistent:true 。 interval 表示监听间隔,以毫秒为单位。
listener(currentStat,previousStat),监听器,一旦文件有变化就会触发这个回调函数,currentStat是更改后当前的文件状态,previousStat表示更改前的状态,这两个参数是fs.Stats类型。(参看“文件夹操作”一节)。
fs.unwatchFile(filename, [listener])
这个方法是停止监听的意思。
filename 要停止监听的文件名。
listener[可选],表示要停止监听的监听器。如果不指定,那么将会停止全部监听文件的监听器。
例
var fs = require("fs"); var handle1 = function(event,filename){ console.log("1") } var handle2 = function(event,filename){ console.log("2") } fs.watchFile("file.txt",handle1); fs.watchFile("file.txt",handle2); setTimeout(function(){ fs.unwatchFile("file.txt",handle1); },20000)
这里有两个监听器 handle1和handle2,当更改file.txt内容时,终端会打印出1 2,当20秒之后,再次更改file.txt文件,会发现终端只打印出 2 ,因为handle1已经被撤销了。
相关文章
- Node.js API实例讲解——http.IncomingMessage
- FIS3 , 为你定制的前端工程构建工具
- Node.js API实例讲解——Buffer的写入方法
- Node.js API实例讲解——Socket 对象
- Node.js API实例讲解——创建http服务器
- Node.js API实例讲解——Buffer的静态方法
- Node.js API实例讲解——https服务器与客户端
- Node.js API实例讲解——FS文件系统概述
- Node.js API实例讲解——进程的操作
- Node.js API实例讲解——二进制类型转换
- Node.js API实例讲解——创建UDP服务器
- Node.js API实例讲解——EventEmitter