在Node.js中操做文件系统html
在Node.js中,使用fs模块来实现全部有关文件及目录的建立,写入及删除操做。在fs模块中,全部对文件及目录的操做均可以使用同步与异步这两种方法。好比在执行读文件操做时,可使用readFile与readFileSync方法。在全部这些方法中,方法名中具备Sync后缀的方法均为同步方法,而不具备Sync后缀的方法均为异步方法。二者的区别是:在使用同步方法执行操做结束以前,不能执行后续代码。好比以下:编程
var fs = require(“fs”); var data = fs.readFileSync(‘./index.html’,’utf8’); // 等待操做结果返回,而后利用该结果。 console.log(data);
而异步方法将操做结果做为回调函数的参数进行返回。在方法调用以后,能够当即执行后续代码,代码以下所示:数组
var fs = require(‘fs’); fs.readFile(‘./index.html’,’utf8’,function(err,data){ console.log(data); }) Console.log(1);// 这句代码先执行
可是异步的方法是不能保证顺序执行的。好比以下缓存
fs.readFile(‘./index.html’,’utf8’,function(err,data){ console.log(data); }) fs.readFile(‘./index2.html’,’utf8’,function(err,data){ console.log(data); })
上面2个异步方法,咱们不能保证那个异步方法先执行完,若是咱们先要第一个方法执行完后,在执行第二个方法,那么代码须要以下写了:app
fs.readFile(‘./index.html’,’utf8’,function(err,data){ console.log(data); fs.readFile(‘./index2.html’,’utf8’,function(err,data){ console.log(data); }) })
咱们先来看看文件的读写操做;以下:异步
一:文件的读操做;函数
读取文件的方法可使用fs模块中的readFile与readFileSync方法,咱们先来了解readFile方法;以下:ui
fs.readFile(filename,[options],callback);编码
在readFile方法中,有三个参数,其中filename参数与callback参数是必须的,options参数是可选的,filename参数用于指定读取文件的完整文件路径及文件名。Options参数值为一个对象,在其中指定读取文件时须要使用的选项,在该参数值对象中可使用flag属性指定对该文件采起什么操做,默认值为 ’r’(若是指定读取的文件不存在,则抛出异常)。能够指定的值以下:spa
'r’: 读取文件,若是文件不存在则抛出异常。
‘r+’: 读取并写入文件,若是文件不存在则抛出异常。
‘w’: 写入文件。若是文件不存在则建立该文件,若是该文件已存在则清空文件内容。
‘wx’: 做用与’w’相似。
‘w+’ 读取并写入文件。若是文件不存在则建立该文件,若是该文件已存在则清空文件内容。
‘wx+’ 做用与’w+’相似。
‘a’ 追加写入文件,若是该文件不存在则建立该文件。
‘ax’ 做用与’a’相似。
‘a+’ 读取并追加写入文件,若是文件不存在则建立该文件。
‘ax+’ 做用与’a+’相似。
在options参数值中,可以使用encoding属性指定使用何种编码格式来读取该文件,可指定属性值为’utf8’,’ascii’与’base64’. Callback参数用于文件读取完毕执行的回调函数。好比下面的方法:
Function(err,data){}
其中第一个参数值为读取文件操做失败时候触发的错误对象,第二个参数值为读取到的文件内容。 当在options参数值对象中使用encoding属性指定编码格式时,该参数值为将文件内容指定编码格式通过编码后的字符串,当不指定编码格式时,该参数值为一个存放了文件中原始二进制内容的缓存区对象。
咱们能够先来看一个简单的readFile方法的使用demo,好比在个人根目录下放一个test.txt文件,内容以下:
这是第一行
这是第二行
而后在应用程序的根目录下放一个app.js文件,代码以下:
var fs = require('fs'); fs.readFile('./test.txt',function(err,data){ if(err) { console.log("读取文件时发生错误"); }else { console.log(data); } });
咱们读取test.txt文件中的内容,若是读取成功,则在控制台将其输出,若是读取失败,则在控制台中输出 ”读取文件时发生错误”.
注意:test.txt文件须要保存编码为utf-8
以下所示:
由上可知:控制台输出的是存取了文件原始二进制数据的缓存区中的内容,若是要将该内容以字符串的形式输出,有2种方式以下:
代码改成以下1:
var fs = require('fs'); fs.readFile('./test.txt',function(err,data){ if(err) { console.log("读取文件时发生错误"); }else { console.log(data.toString()); } });
第二种形式是:咱们能够指定options参数并将encoding属性值指定为某种编码格式,则回调函数中的第二个参数值返回将文件内容根据指定编码格式进行编码后的字符串。以下代码:
var fs = require('fs'); fs.readFile('./test.txt','utf8',function(err,data){ if(err) { console.log("读取文件时发生错误"); }else { console.log(data); } });
运行以下:
在使用同步方式读取文件时,使用readFileSync方法,该方法使用以下:
var data = fs.readFileSync(filename,[options]);
在readFileSync方法中,使用两个参数,这两个参数的含义及指定方法与readFile方法中使用filename参数与options 参数的含义及指定方法彻底相同。
以下代码:
var fs = require('fs'); try{ var data = fs.readFileSync('./test.txt','utf8'); console.log(data); }catch(e){ console.log("读取文件时发生错误。"); }
执行效果如上所示:
二:文件的写操做;
在完整写入一个文件时,咱们可使用fs模块的writeFile方法或writeFileSync方法。使用方法以下所示:
fs.writeFile(filename,data,[options],callback);
在writeFile方法中,使用4个参数,其中filename,data,callback为必须指定的参数,[options]为可选参数,filename参数用于指定须要被写入文件的完整文件路径及文件名,data参数用于指定须要写入的内容,参数值能够为一个字符串或一个buffer对象,该字符串或缓存区中的内容将被完整地写入到文件中。Options参数值为一个对象,在其中指定写入文件时须要使用的选项,在该参数值对象中可使用以下所示的属性值。
1. flag属性:用于指定对该文件采起何种操做,默认值’w’(文件不存在时建立该文件,文件已存在时重写该文件,)可指定值及其含义与readFile方法中使用的options参数值中的flag属性的可指定值及其含义相同。
2. mode属性:用于指定当文件被打开时对该文件的读写权限,默认值为0666(可读写)。该属性值及fs模块中的各方法中的mode参数值的指定方法以下所示:使用4个参数组成mode属性值或mode参数值,其中第一个数字必须为0,第二个数字用于规定文件或目录全部者的权限,第三个数字用于规定文件或目录全部者所属用户组的权限,第四个数字规定其余人的权限,能够设定的数字以下所示:
1. 执行权限
2. 写权限
3. 读权限
若是须要设置读写等复合权限,能够对以上三个数字进行加运算,好比使用 2+4=6来设置读写权限。
下面咱们来看看demo,其中app.js代码以下:
var fs = require('fs'); fs.writeFile('./message.txt',"这是第一行。\r\n这是第二行.",function(err){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } });
在上面的代码中,咱们将在应用程序的根目录建立一个message.txt文件并在其中写入两行文字。咱们能够去看下根目录就知道,就生成了一个message.txt文件了。
接下来咱们看一个在文件中写入缓存区中数据的代码,以下代码:
var fs = require('fs'); var data = new Buffer("我喜好编程"); fs.writeFile('./message.txt',data,function(err){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } });
如上代码,咱们能够看到在message.txt中,写文件操做成功,我喜好编程几个字也在message.txt中了。
接下来咱们能够经过options参数中设置flag属性值的方式修改对文件的操做方式,好比在代码中,咱们可使用writeFile方法在message.txt文件尾部追加”这是追加的数据” 文字。好比以下代码:
var fs = require('fs'); var options = { flag: 'a' }; fs.writeFile('./message.txt','这是追加的数据。',options,function(err){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } });
进入文件的根目录运行下 便可 能够看到,文字被添加进去了。
内容变成以下:
我喜好编程这是追加的数据。
能够经过在options参数中设置encoding属性值的方式指定在文件中写入数据时使用的编码方式,好比以下我在个人根目录下有2张不一样的图片,分别是1.gif图片和2.gif图片,如今咱们能够先使用readFile读取1.gif图片后使用base64编码,在readFile方法的回调函数中使用writeFile方法且该方法中使用base64编码将读取到1.gif图片复制到2.gif图片上,也就是说对以前的2.gif图片进行覆盖。
代码以下:
var fs = require('fs'); fs.readFile("./1.gif",'base64',function(err,data){ fs.writeFile('./2.gif',data.toString(),'base64',function(err){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } }); });
运行下便可,而后咱们继续查看2.gif图片能够看到,和1.gif图片同样的。
writeFileSync:
在使用同步方式写入文件时,使用writeFileSync方法,该方法使用以下:
fs.writeFileSync(filename,data,[options]);
上面的同步方法和writeSync方法中放filename参数,data参数,[options]参数的含义及指定方法彻底相同。
appendFile和appendFileSync方法
在将一个字符串或一个缓存区中的数据追加到一个文件底部时,咱们可使用fs模块中的appendFile和appendFileSync方法。
fs.appendFile(filename,data,[options],callback);
在appendFile方法中,使用4个参数,其做用及指定方法与writeFile方法所使用的4个参数的做用与指定方法大体相同,区别在于,在options参数值对象中,flag属性的默认属性值为’a’(在文件底部追加写入数据,若是文件不存在,则建立该文件)。
以下代码:
var fs = require('fs'); fs.appendFile('./message.txt','这是追加的数据2。','utf8',function(err){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } });
运行下便可看到数据了。若是message.txt文件不存在,则建立该文件。
在使用同步方式在文件底部追加数据时,可使用appendFileSync方法,该方法的使用方式以下:
fs.appendFileSync(filename,data,[options]);
该方法的参数和appendFile方法的参数的含义和指定方法彻底相同。
三:从指定位置处开始读写文件。
open:
如何从指定位置处开始读写文件的处理,咱们首先须要使用fs模块中的open方法或openSync方法打开文件。open方法使用方式以下:
fs.open(filename,flags,[mode],callback);
在open方法中,可使用4个参数,其中filename,flags参数与callback参数是必须项。mode参数是可选项,filename,flags,[mode]参数的做用及其指定方法与writeFile相同。
Callback参数用于指定文件打开操做执行完毕时的回调函数,以下所示:
Function(err,id){}
其中第一参数值为打开文件操做失败时所触发的错误对象,第二个参数值为一个整数值,表明打开文件时返回的文件描述符
以下demo
var fs = require('fs'); fs.open('./message.txt','r',function(err,id){ console.log(id); });
截图以下:
openSync:
在使用同步方式打开文件时,使用openSync方法,以下所示:
var fd = fs.openSync(filename,flags,[mode]); 参数与上面open参数同样的。
在打开文件后,能够在回调函数中使用fs模块中的read方法或readSync方法从文件的指定位置处读取文件,也能够调用fs模块中的write方法或writeSync方法从文件的指定处开始写入数据。
read:
下面咱们下来看看read方法,该方法从文件的指定位置处读取文件,一直读取到文件底部,而后将读取到的内容输出到一个缓存区中,该方法使用以下所示:
fs.read(fd,buffer,offset,length,position,callback);
在read方法中,使用6个参数,其中fd参数值必须为open方法所使用的回调函数中返回文件描述符或openSync方法返回的文件描述符; buffer参数值为一个Buffer对象,用于指定将文件数据读取到那个缓存区中,offset参数值,length参数值与position参数值均为一个整数,其中offset参数用于指定向缓存区中写入数据时的开始写入位置(以字节为单位),length参数用于指定从文件中读取的字节数,position参数用于指定读取文件时的开始位置(以字节为单位)。Callback参数用于指定文件读取操做执行完毕时执行的回调函数,以下
Function (err,bytesRead,buffer){}
Callback有3个参数,err为读取文件操做失败时所触发的错误对象;bytesRead为一个整数值,表明实际读取的字节数,buffer为被读取的缓存区的对象。
咱们来看看代码以下,咱们将使用read方法从应用程序根目录下的内容为”我喜好编程”字符串的message.txt文件中将”喜好编”这三个字符读取到一个缓存区中,而后从缓存区中读取这三个字符并将其在控制台输出;以下代码:
var fs = require('fs'); fs.open('./message.txt','r',function(err,fd){ var buf = new Buffer(255); // 一个汉字的utf编码为三个字节数据 fs.read(fd,buf,0,9,3,function(err,bytesRead,buffer){ console.log(buffer.slice(0,bytesRead).toString()); }); });
演示以下:
其中message.txt内容以下:
我喜好编程这是追加的数据。这是追加的数据2。
上面代码是先打开message.txt文件,而后offset参数用于指定向缓存区中写入数据时的开始写入位置,为0;length=9 意思是:指定从文件中读取的字节数,因为一个汉字的utf编码为3个字节数据,所以中文为3个。Position=3 用于指定读取文件时的开始位置,所以从”喜”字开始读取。
read方法的position参数值用于指定读取文件时的开始位置(以字节为单位),若是该参数为null,将从文件的当前读取位置处(前一次读取时的开始位置+读取字节数)开始读取文件。以下代码:
var fs = require('fs'); fs.open('./message.txt','r',function(err,fd){ var buf = new Buffer(255); // 一个汉字的utf编码为三个字节数据 fs.read(fd,buf,0,9,3,function(err,bytesRead,buffer){ console.log(buffer.slice(0,bytesRead).toString()); // 从文件的当前读取位置继续往下读取 fs.read(fd,buf,0,3,null,function(err,bytesRead,buffer){ console.log(buffer.slice(0,bytesRead).toString()); }); }); });
演示以下:
readSync:
在使用同步方式打开文件时,使用readSync方法,代码以下:
var bytesRead = fs.readSync(fd,buffer,offset,length,position);
同步中的readSync和read方法里面的参数彻底相同,该方法返回实际从文件中读取到的字节数。
下面是同步方式的代码以下:
var fs = require('fs'); fs.open('./message.txt','r',function(err,fd){ var buf = new Buffer(255); // 一个汉字的utf编码为三个字节数据 var bytesRead = fs.readSync(fd,buf,0,9,3); console.log(bytesRead); console.log(buf.slice(0,bytesRead).toString()); });
截图以下:
write方法和writeSync方法
在打开文件以后,可使用fs模块中的write方法或writeSync方法从一个缓存区中读取数据而且从文件的指定处开始写入数据。
write方法使用以下:
fs.write(fd,buffer,offset,length,position,callback)
在write方法中,使用6个参数,fd参数值必须为open方法或者openSync方法所使用的回调函数中返回的文件描述符;buffer参数值为一个Buffer对象,用于指定从哪一个缓存区中读取数据,offset,length及position参数值均为一个整数值,其中offset参数用于指定从缓存区中读取数据时的开始读取位置(以字节为单位);length参数用于指定从缓存区中读取的字节数,position参数值用于指定写入文件时的开始位置(以字节为单位)。
Callback参数用于指定文件写入操做执行完毕时执行的回调函数,以下:
Function (err,written,buffer){}
该回调使用三个参数,err参数为写入文件操做失败时所触发的错误对象;written参数值为一个整数值,表明被写入的字节数;buffer参数值为一个Buffer对象,表明被读取的缓存区对象;
下面咱们来看看write方法的demo,咱们将首先使用”我喜好编程”字符串建立一个缓存区对象,而后使用write方法从缓存区中读取”喜好编”这三个字符并将其写入message.txt文件中,代码以下:
var fs = require('fs'); var buf = new Buffer("我喜好编程"); fs.open('./message.txt','w',function(err,fd){ fs.write(fd,buf,3,9,0,function(err,written,buffer){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } }); });
运行命令后,能够打开message.txt文件,能够看到内容为:‘喜好编’
Write方法的position参数值用于指定写入文件时的开始位置(以字节为单位),当参数值为null时,将从文件的当前被写入位置处(前一次写入时的开始位置+写入字节数)开始写入文件。
咱们接着修改app.js代码,在将 ”喜好编”字符串写入到应用程序根目录的message.txt文件中后,追加写入”程”字符串。代码以下:
var fs = require('fs'); var buf = new Buffer("我喜好编程"); fs.open('./message.txt','a',function(err,fd){ fs.write(fd,buf,3,9,0,function(err,written,buffer){ fs.write(fd,buf,12,3,null,function(err,written,buffer){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); } }); }); });
Message.txt内容以下:
喜好编程
在使用同步方式写入文件时,使用writeSync方法,使用方式以下:
fs.writeSync(fd,buffer,offset,length,position);
上面的5个参数与write方法的参数彻底相同。
close方法与closeSync方法
在fs模块中,提供close方法与closeSync方法以关闭文件;
使用以下:
fs.close(fd,[callback]);
在close方法中,使用2个参数,其中fd参数值必须为open方法所使用的回调函数中返回的文件描述符或openSync返回的描述符,callback参数为一个可选参数,用于指定关闭文件操做结束时执行的回调函数,在回调函数中使用一个参数,参数值为关闭文件操做失败时触发的错误对象。那咱们如今能够在咱们的根目录下建立a.txt文件并在其中写入 “我喜好编程”字符串,而后关闭a.txt文件。
var fs = require('fs'); var buf = new Buffer("我喜好编程"); fs.open('./a.txt','wx',function(err,fd){ fs.write(fd,buf,0,15,0,function(err,written,buffer){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); fs.close(fd); } }); });
运行下能够看到在根目录下生成a.txt文件,内容以下:
我喜好编程;
同步方式的close方法的使用方式以下所示:
fs.closeSync(fd);
使用一个参数,参数值为open方法所使用的回调函数中返回的文件描述符或openSync方法返回的文件描述符。
在使用write方法或writeSync方法在文件中写入数据时,操做系统的作法是首先将该部分数据读到内存中,再把数据写到文件中,当数据读完时并不表明数据已经写完,由于还有部分数据有可能留在内存缓冲区中,这时若是咱们调用close方法或closeSync方法关闭文件,那么这部分的数据就会丢失,这时咱们可使用fs模块中的fsync方法对文件进行同步操做,即将内存缓冲区中的剩余数据所有写入文件,该方法使用以下:
fs.fsync(fd,[callback]);
代码能够以下:
var fs = require('fs'); var buf = new Buffer("我喜好编程"); fs.open('./a.txt','w',function(err,fd){ fs.write(fd,buf,0,15,0,function(err,written,buffer){ if(err) { console.log("写文件操做失败"); }else { console.log("写文件操做成功"); fs.fsync(fd); fs.close(fd); } }); });
四:建立与读取目录
4.1 建立目录;
在fs模块中,可使用mkdir方法建立目录,使用方法以下:
fs.mkdir(path,[mode],callback);
其中path参数与callback参数为必须输入的参数,[mode]为可选参数,path参数用于指定须要被建立的目录的完整路径及目录名;mode参数值用于指定该目录的权限,默认值为0777(表示任何人可读写该目录);callback参数用于指定建立目录操做完毕时调用的回调函数,该回调函数中使用一个参数,参数值为建立目录操做失败时触发的错误对象。
代码以下:
var fs = require('fs'); fs.mkdir('./test',function(err){ if(err) { console.log("建立目录操做失败"); }else { console.log("建立目录操做成功"); } });
演示以下:
咱们看到在咱们的目录下 就建立了一个test目录;
在使用同步方式建立目录时,可使用fs模块中的mkdirSync方法,该方法使用以下:fs.mkdirSync(path,[mode]);
上面2个参数的含义与mkdir中的path,[mode]参数的含义同样。
4.2读取目录;
在fs模块中,可使用readdir方法读取目录,该方法使用以下:
fs.readdir(path,callback);
在readdir方法中,使用2个参数,其中path参数用于指定须要被读取的目录的完整路径及目录名,callback参数用于指定读取目录操做完毕时调用的回调函数,该回调函数以下所示:
Function(err,files){};
第一个参数为读取目录操做失败时触发的错误的对象,第二个参数值为一个数组,其中存放了读取到的文件中的全部文件名。
下面咱们来演示下读取根目录下的全部文件的代码以下:
var fs = require('fs'); fs.readdir('./',function(err,files){ if(err){ console.log("读取目录操做失败"); }else { console.log(files); } });
演示以下:
在使用同步方式读取目录时,可使用readdirSync方法,该方法使用以下:
var file = fs.readdirSync(path);
在readdirSync方法中,使用一个参数,用于指定须要读取的目录的完整路径及目录名,该方法返回被读取目录中全部文件名构成的数组;
五:查看与修改文件或目录的信息
1. 检查文件或目录是否存在。
在fs模块中,可使用exists方法检查一个文件或目录是否存在,该方法的使用方式以下所示:
fs.exists(path,callback);
在exists方法中,可使用两个参数,path参数用于指定须要被检查的文件或目录的完整路径及文件名或目录名,callback参数用于指定检查文件或目录信息操做完毕时执行的回调函数,以下:
Function(exists){}
在该回调函数中,使用一个参数,当文件或目录存在时,该参数值为true,不然为false。以下代码所示:
var fs = require('fs'); fs.exists('./message.txt',function(exists){ if(exists) { console.log("该文件存在"); }else { console.log("该文件不存在"); } });
若是根目录有message.txt文件的话,说明文件已存在,不然的话 不存在。
在使用同步方法检查文件是否存在时,可使用fs模块中的existSync方法,该方法的使用方式以下:
var exists = fs.existsSync(path);
2. 获取文件或目录的绝对路径
在fs模块中,可使用realpath方法获取一个文件或目录的绝对路径,该方法使用以下所示:
fs.realpath(path,[cache],callback);
path参数与callback参数为必须的,cache参数为可选的,其中path参数为须要查看的文件或目录的完整路径,cache参数值为一个对象,其中存放了一些预先指定的路径,callback参数用于指定获取文件或目录的绝对路径操做完毕时执行的回调函数,该回调函数使用两个参数,其中err参数值为获取文件或目录的绝对路径操做失败时触发的错误对象,resolvedPath参数值为获取到的文件或目录的绝对路径。
以下代码:
var fs = require('fs'); fs.realpath('./message.txt',function(err,resolvedPath){ if(err) { console.log("获取文件失败"); }else { console.log(resolvedPath); } });
演示以下:
在使用同步方式获取文件或目录的绝对路径时,可使用realpathSync方法,该方法使用以下所示:
var resolvedPath = fs.realpathSync(path,[cache]);
3. 修改文件或目录的读写权限
在fs模块中,可使用chmod方法修改文件或目录的读写权限,该方法使用以下所示:
fs.chmod(path,mode,callback);
在chomd方法中,可使用三个参数,path参数用于指定须要被修改读写权限的文件的完整路径及文件或目录名,mode参数用于指定修改后的文件或目录读写权限;callback参数用于指定修改文件读写权限操做完成后执行的回调函数,该回调函数使用一个参数,参数值为修改文件读写权限操做失败的触发错误对象。
以下代码:
var fs = require('fs'); // 0600表明全部者可读写,其余人没有任何权限 fs.chmod('./message1.txt',0600,function(err){ if(err) { console.log("修改文件权限操做失败"); }else { console.log("修改文件权限操做成功"); } }); // 0644表明全部者可读写,其余人只读 fs.chmod('./message2.txt',0644,function(err){ if(err) { console.log("修改文件权限操做失败"); }else { console.log("修改文件权限操做成功"); } }); // 0755表明全部者全部权限,其余全部人可读和执行 fs.chmod('./message3.txt',0755,function(err){ if(err) { console.log("修改文件权限操做失败"); }else { console.log("修改文件权限操做成功"); } }); // 0740表明全部者全部权限,全部者所在的组只读 fs.chmod('./message4.txt',0740,function(err){ if(err) { console.log("修改文件权限操做失败"); }else { console.log("修改文件权限操做成功"); } });
在使用同步方式修改文件或目录的读写权限时,可使用fs模块中的chmodSync方法,使用方法以下:
fs.chmodSync(path,mode);