您的位置:首页 > Web前端 > Node.js

Node.js入门笔记(4):文件系统(fs)

2016-12-02 22:30 1536 查看

文件系统(FileSystem)

文件系统模块

对于文件无外乎创建修改添加。

File System - 文件系统模块 - require('fs')

fs模块是核心模块,需要使用require导入后使用。该模块提供了操作文件的一些API

fs.open(path, flags, [mode], callback)

–异步版的打开一个文件。一共接受4个参数,3个可选

path:要打开文件的路径

flags:打开方式——常用的有读()/写。会影响后续的打开方式

[MODE]:设置文件的模式:读、写、执行4/2/1

callback:回调文件打开后的执行后续又包括两个参数(1)err:文件打开失败的错误保存在err,成功则为null。(2)fd:被打开文件的标示和定时器,后续可以根据编号查找打开的是哪个文件。

在1.js同目录下创建一个内容为abcd的1.txt文件,对1.js输入

var fs=require('fs');//引入fs模块

fs.open('1.txt','r',function (err,fd) {//读
console.log(err);//返回null,证明打开成功
console.log(fd);//返回3
});

如果你打开

fs.openSync(path, flags, [mode])

–fs.open() 的同步版,读取方式是以同步的方式执行。不是以回调的方式处理。现在来看看他俩的区别。

I/O读取是需要时间的。异步加载的顺序:

var fs=require('fs');//引入fs模块
fs.open('1.txt','r',function (err,fd) {
console.log(fd);//第二个输出
});
console.log('ok');//第一个输出

而同步不需要回调。直接返回fd值。代码就好看多了。

var fd=fs.openSync('1.txt','r');//同步不需要回调,直接有返回值
console.log(fd);
console.log('ok2');

fs.read(fd, buffer, offset, length, position, callback)

–从指定的文档标识符fd读取文件数据。fd就是open回调函数中的标示编号,buffer对象,offset:新的内容添加到buffer的其实位置,length添加到buffer的长度,position:读取位置,callback回调函数

var fs=require('fs');//引入fs模块
fs.open('1.txt','r',function (err,fd) {
if(err){
console.log('失败')
}else{
var bf1=new Buffer(10);
console.log(bf1);//定义用来存放内容的buffer
fs.read(fd,bf1,0,4,null,function (err,len,newBf) {
//console.log(err)//返回为null
//console.log(len)//返回4
//console.log(newBf)//就是被修改后的bf1
console.log(bf1);
});//把读取的内容(4位),从第0位起放到bf1中
}
});

输出结果:



buffer对象的前4位就是abcd。

fs.readSync(fd, buffer, offset, length, position)

–fs.read 函数的同步版本。 返回bytesRead的个数。

fs.write(fd, buffer, offset, length[, position], callback)

–通过文件标识fd,向指定的文件中写入buffer。fd标识,buffer:要写入的数据,offset:在buffer中要写入数据的起始位置,length要写入buffer数据的长度,position:fd中的起始位置,callback回调。当对文件进行写操作时,open方式应该是
r+
而不是
r


var fs=require('fs');//引入fs模块
fs.open('1.txt','r+',function (err,fd) {
if(err){
console.log('打开失败')
}else{
var bf1=new Buffer('123');
fs.write(fd,bf1,0,3,0,function () {
console.log(arguments);
});//针对fd文件写入bf1的内容。读取1.txt第0到第3个的内容,并从第0个开始修改为123
}
});

输出
{ '0': null, '1': 3, '2': <Buffer 31 32 33> }


再看1.txt:内容变成了
123d


fs.write(fd, data[, position[, encoding]], callback)

–把data写入到文档中通过指定的fd,如果data不是buffer对象的实例则会把值强制转化成一个字符串。

以上那么长一段可以有简化写法:

fs.write(fd,'1234',5,'utf-8');
——从第4位开始添加abcd——>1234abcd

fs.writeSync(fd, buffer, offset, length[, position])

–fs.write() 的同步版本

fs.writeSync(fd, data[, position[, encoding]])

–fs.write() 的同步版

fs.close(fd, callback)

–关闭一个打开的文件

fs.closeSync(fd)

–fs.close() 的同步版本

fs.writeFlie(filename, data, [options], callback)

–异步的将数据写入一个文件,如果文件不存在则新建, 如果文件原先存在,会被替换。 data 可以是一个string,也可以是一个原生buffer。

想一个指定的文件写入数据。如果存在会覆盖掉原来的。

var fs=require('fs');//引入fs模块
var filename='2.txt';
fs.writeFile(filename,'hello',function () {
console.log(arguments);
});

中午段代码创建你了一个2.txt,把hello写进去了。

fs.writeFileSync(filename, data, [options])

–fs.writeFile的同步版本。注意:没有callback,也不需要

fs.appendFile(filename, data, [options], callback)

–异步的将数据添加到一个文件的尾部,如果文件不存在,会创建一个新的文件。 data 可以是一个string,也可以是原生buffer。

var fs=require('fs');//引入fs模块
var filename='2.txt';
fs.appendFile(filename,'-djtao',function () {
console.log(arguments)
});

fs.appendFileSync(filename, data, [options])

–fs.appendFile的同步版本。

fs.readFile(filename, [options], callback)

–异步读取一个文件的全部内容

var fs=require('fs');//引入fs模块

fs.readFile('2.txt',function () {
console.log(arguments)
});

打印结果是:

{ '0': null, '1': <Buffer 64 6a 74 61 6f 2d 64 6a 74 61 6f> }

第一个参数是错误,第二个参数个buffer对象。描述是2.txt的内容(djtao-djtao)。

所以完整写法应该是:

var fs=require('fs');//引入fs模块

fs.readFile('2.txt',function (err,value) {
//console.log(arguments)
if(err){
console.log('读取失败')
}else{
console.log(value.toString())//2.txt的文本内容
}
});

fs.readFileSync(filename, [options])

–fs.readFile的同步版本

fs.exists(path, callback)

–检查指定路径的文件或者目录是否存在

直接来看一个结合写入和追加判断的方法

var fs=require('fs');//引入fs模块
var filename='3.txt';
fs.exists(filename,function (isExists) {
console.log(isExists);//
if(!isExists){//如果不存在,写入djtao
fs.writeFile(filename,'djtao',function (err) {
if(err){
console.log('出错了,创建失败');
}else{
console.log('创建新的文件成功并写入内容')
}
})
}else{//如果存在,追加-djtao
fs.appendFile(filename,'-djtao',function (err) {
if(err){
console.log('新的内容追加失败');
}else{
console.log('新的内容追加成功!');
}
})
}
})

使用appendFile实际上是不必要的。这里为了演示机制。

第一次运行结果,因为3.txt原本是不存在的,所以创建3.txt并写入文件‘djtao’:



我们在运行一次,此时因为存在了3.txt,所以3.txt内容变成了:djtao-djtao结果是:



fs.existsSync(path)

–fs.exists的同步版本

var fs=require('fs');//引入fs模块
var filename='4.txt';
//以下采用同步的写法:
if(!fs.existsSync(filename)){//如果文件不存在
fs.writeFileSync(filename,'djtao');
console.log('新文件创建成功!');

}else{//如果文件存在,追加
fs.appendFileSync(filename,'-djtao')
console.log('新内容追加成功!')
}

从结果来看效果和上例是一样的。

fs.unlink(path, callback)

–删除一个文件

var fs=require('fs');//引入fs模块

fs.unlink('3.txt',function (err) {
if(err){
console.log('删除失败')
}else{
console.log('删除成功')
}
});

回调函数只有一个参数err,如果不存在要删除的文件,err就不为null。

fs.unlinkSync(path)

–fs.unlink() 的同步版本

fs.rename(oldPath, newPath, callback)

–重命名

var fs=require('fs');//引入fs模块

fs.rename('2.txt','2.newTxt',function (err) {
if(err){
console.log('重命名失败')
}else{
console.log('成功!')
}
})

fs.renameSync(oldPath, newPath)

–fs.rename() 的同步版本



fs.stat(path, callback)

–读取文件信息

var fs=require('fs');//引入fs模块

fs.stat('1.txt',function (err,info) {
//console.log(arguments)
})

info是个json信息,包括def创建时间,修改时间,字节长度,是属于文件(mode:33206)还是文件夹(mode:16822)等等。不同操作系统返回的内容有所不同。

fs.statSync(path, callback)

–fs.stat() 的同步版本



fs.watch(filename, [options], [listener])

–观察指定路径的改变,filename 路径可以是文件或者目录

它是一个事件。(不稳定,可能有bug。慎重使用)

第三个监听器是个回调函数,路径被改变时会被触发。

fs.mkdir(path, [mode], callback)

–创建文件夹,path指的是路径,mode是指读写模式,最后一个是回调。

fs.rmdir(path, callback)

–删除文件夹

为了演示,以下结合fs.rmdir进行操作:在当前目录下创建一个名字为1的文件夹,如果1文件夹已经存在,就删掉。

var fs=require('fs');//引入fs模块
fs.mkdir('./1',function (err) {
if(err){
console.log('创建失败,将删除名字为1的文件夹');
fs.rmdir('./1',function (eRr) {
if(!eRr){
console.log('删除成功')
}else{
console.log('删除失败!')
}
})
}else{
console.log('成功创建了一个名为1的文件夹')
}
});//在当前目录创建一个1文件夹。如果该文件夹存在则删除掉。

通过此方法也可以判断一个文件夹是否存在。

fs.mkdirSync(path, [mode])

–fs.mkdir的同步版本

fs.rmdirSync(path)

–fs.rmdir的同步版本

fs.readdir(path, callback)

–读取文件夹

接下来读取当前文件夹

var fs=require('fs');//引入fs模块
fs.readdir('./',function (err,fileList) {
console.log(err);
console.log(fileList);
});

输出

null
[ '1', '1.js', '1.txt', '2.js', '2.new.txt', '3.js' ]

表示当前文件夹下存在以下文件(夹)。存在一个数组里面。

接下来要进一步优化,做一个文件管理系统。之前有个stat方法可以判断文件信息.

var fs=require('fs');//引入fs模块
fs.readdir('./',function (err,fileList) {

fileList.forEach(function (f) {//循环数组每个元素,参数f每次循环的元素
//判断当前是文件还是文件夹
fs.stat(f,function (err,info) {
if(info.mode==16822){
console.log('[文件夹]'+f);
}else if(info.mode==33206){
console.log('[文件]'+f);
}else{
console.log('[其它]'+f);
}
});
})

});

输出结果

[文件夹]1
[文件]1.js
[文件]1.txt
[文件]2.js
[文件]2.new.txt
[文件]3.js

fs.readdirSync(path)

–fs.readdir同步版本
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: