node基础学习——操作文件系统fs

时间:2023-11-15 16:39:02

操作文件系统fs

1.在Node.js中,使用fs模块来实现所有有关文件及目录的创建、写入及删除。在fs模块中,所有对文件及目录的操作都可以使用同步与异步两种方法,具有Sync后缀的方法均为同步方法。两者的区别:同步的方法立即返回操作结果,在使用同步方法执行的操作结果之前,不能执行其他代码;异步相反。

备注: []括号是选填参数

备注:mac 怎么输入圆圈数字? ———— 在中文输入法下按组合键option+shift+b

2.1对文件执行读写操作

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

参数:filename参数用于指定读取文件的完整文件路径及文件名

Options参数值为一个对象,在其中指定读取文件时需要使用的选项,flags[r]对文件采取什么样的操作,encoding属性编码格式

同步方法: var data = fs.readFileSync(filename,[options]);

2.1.2 fs.writleFile(filename,data,[options],callback);

参数:options属性和readFile的一样,其中多一个mode属性:用于指定当文件被打开时对该文件的读写权限,默认值为0666(可读写)

Mode属性使用4个数字来表示:第一个数字必须是0,第二个数字用于规定文件或目录所有者的权限,第三个数字用于规定文件或目录所有者所属用户组的权限,第四个数字规定其他人的权限。可以设定的数字如下所示: 1执行权限,2写权限,4读权限

同步方法: var data = fs.writeFileSync(filename,data,[options])

2.2 从指定位置处开始读写文件

2.2.1 fs.open(filename,flags,[options],callback);

Callback = function(err,fd){…} 参数fd:表示打开文件返回的文件描述(在windows操作系统中,文件描述也称为文件句柄)

同步方法: var fd = fs.openSync(filename,flags,mode);

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

Callback = function(err,bytes,buffer){…}

参数:buffer用于指定将文件数据读取到哪个缓冲区中,offset参数用于指定向缓冲区中写入数据的开始位置(以字节为单位),length参数用于指定从文件中读取的字节数,position参数用于指定读取文件时的开始位置。callback回调函数参数:bytes代表实际读取的字节数(由于文件的开始读取位置+指定读取的字节数可能大于文件长度,指定读取的字节数可能并不等于实际读取到的字节数),buffer参数值为被读取到的缓存区对象。

同步方法:var bytesRead = fs.readSync(fd,buffer,offset,length,position);

2.2.3 fs.write(fd,buffer,offset,length,position,callback);

callback = function(err,written,buffer){…}

参数:和fs.read()一样。回调函数written代表被写入的字节数。

同步方法: var bytesWrite = fs.writeSync(fd,buffer,offset,length,posiioon);

2.2.4 当文件的读写操作完成之后,通常需要关闭该文件,尤其是文件在以排他方式打开的时候,在fs模块中,提供了两种关闭文件的方法

a->fs.close(fd,[callback])

同步方法:fs.closeSync(fd);

b->fs.fsync(fs,[callback])

同步方法:fs.fsyncSync(fd);

两者区别:在使用write()或者writeSync()方法写入数据时,操作系统的做法是首先将该部分的数据读到内存中,再把数据写到文件中,当数据读写时并不代表数据已经写完,因为还有一部分有可能会流在缓冲区中。这是如果调用close方法或者closeSync方法关闭文件,那么这部分数据可能会丢失,这时,我们可以调用fs模块中的fsync方法对文件进行同步操作,即将内存缓冲区中的剩余数据全部写入文件。

内存缓冲区功能: http://product.pconline.com.cn/itbk/software/dnyw/1707/9613894.html

2.3 创建与读取目录

2.3.1创建目录

Fs.mkdir(path,[mode],callback);

Callback = function(err){…}

path参数用于指定需要被创建的目录的完整路径及目录名,mode参数用于指定目录的权限(默认值为0777,表示任何人可读可写该目录)

同步方法: fs.mkdirSync(path)

2.3.2 读取目录

Fs.readdir(path,callback)

Callback = function(err,files){…}

files参数值为一个数组,其中存放了读取到的文件中所有文件名。

同步方法:fs.readdirSync(path)

2.4查看与修改文件或目录的信息

2.4.1查看目录或文件信息

fs.stat(path,callback);

fs.lstat(path,callback);

Callback = function(err,stats){…}

参数:path参数用于指定需要被查看文件或目录的完整路径及文件名或目录名。回调函数stats参数值为一个对象,该对象拥有如下所示的常用一些方法:

isFile方法:用于判断被查看的对象是否为一个文件,如果是的话返回true,否则返回false

isDirectory方法:用于判断被查看的对象是否为一个目录,如果是的话返回true,否则返回false

mode:该属性值为使用数值代表的文件或目录的权限标志

nlink:该属性值为文件或目录的硬连接数量

size:该属性值为文件尺寸

Atime:该属性值为文件的访问时间 (access)

Mtime:该属性值为文件的修改时间 (modify)

Ctime:该属性值为文件的创建时间

同步方法:var stats = fs.statSync(path);

var stats = fs.lstatSync(path);

2.4.2 在使用open方法或openSync方法打开文件并返回文件描述后,可以使用fs模块中的fs.fstat方法查询被打开的文件信息,该方法的使用方式如下所示:

Fs.fstat(fd,callback);

同步方法:var stats = fs.fstatSync(path);

2.4.3检查文件或目录是否存在

Fs.exists(path,callback);

Callback = function(exists){…}

参数:path参数用于指定需要被检查的文件或目录的完整路径及文件名或目录名。回调函数exists如果返回true,表示存在,否则就不存在。

同步方法:var exists = fs.existsSync(path);

2.4.3获取文件或目录的绝对路径

Fs.realpath(path,[cache],callback)

Callback = function(err,resolvePath){…}

参数:path参数用于指定需要查看的文件或目录的完整路径,cache可选参数,为一个对象,其中存放了一些指定的路径。回调函数resolvePath参数值为获取到的文件或目录的绝对路径。

同步方法: var resolvePath = fs.realPath(path,[cache]);

2.4.4 修改文件访问时间及修改时间

Fs.utimes(path,atime,mtime,callback);

callback = function(err){…}

参数:path参数用于指定需要被修改时间的文件的完整路径及文件名,atime参数用于指定修改后的访问时间,mtime参数用于指定修改后的修改时间。

同步方法: fs.utimesSync(path,atime,mtime);

2.4.5 在使用open或openSync方法打开文件并返回文件描述符后,可以使用fs模块中的futimes方法修改文件的访问时间或修改时间,该方法的使用方式如下:

Fs.futimes(fd,atime,mtime,callback);

同步方法: fs.futimesSync(fd,atime,mtime)

2.4.6 修改文件或者目录的读写权限

Fs.chmod(path,mode,callback);

Callback = function(err){…}

参数:path参数用于指定需要被修改读写权限的文件的完整路径及文件或目录名,mode参数用于指定修改后的文件或目录代谢权限

常用权限:

0600代表所有者可读写,其他人没有任何权限

0644代表所有这可读写,其他人只读

0755代表所有者有所有权限,其他所有人可读和执行

0740代表所有者有所有权限,所有者所在的组织只读

同步方法:fs.chmodSync(path,mode)

2.4.7 在使用open或openSync方法打开文件并返回文件描述符后,可使用fs模块中的fchmld方法或fchmodSync方法修改文件的读写权限。

Fs.fchmod(fd,mode,callback);

同步方法: fs.fchmodSync(fd,mode)

2.5 对文件或目录的其他操作

2.5.1移动文件或目录

Fs.rename(oldPath,newPath,callback);

Callback = function(err){…}

参数:oldPath参数用于指定被移动文件或目录的完整路径及文件名或目录,newPath参数用于指定移动后该文件或目录的完整路径及文件名或目录

同步方法:fs.renameSync(oldPath,newPath)

2.5.2创建或删除文件的硬链接

硬链接:实际上是文件的一个或多个文件名。在操作系统中,一个文件被创建之后就拥有了个文件名,因此该文件的硬链接数量为1。但是我们可以通过某种特殊的操作为该文件在指定一个文件名,而这中特殊的操作称为对该文件创建硬链接。在对该文件创建一个硬链接之后,虽然表面上看起来拥有了两个不同的文件,但是在硬盘中这两个只不过是同一个文件的多个硬链接,如果修改了一个文件中的内容,再打开另外一个文件,就会看见另一个文件中的内容也被修改了。

软链接和硬链接:http://www.jianshu.com/p/dde6a01c4094

Fs.link(srcpath,dstpath,callback)

参数:srcpath参数用于指定需要被创建硬链接的文件的完整路径及文件名,dstpatch参数用于指定被创建的硬链接的完整路径及文件名,该硬链接与原文件必须在同一卷中。

同步方法: fs.linkSync(srcpath,dstpath)

2.5.3删除硬链接

在fs模块中,可以使用unlink方法删除文件的硬链接。在对文件创建多个硬链接之后,这些硬链接互相独立的关系(最初存在的文件为该文件的第一个硬链接),删除任何一个硬链接,其他硬链接依然存在,但是如果删除的硬链接为该文件的最后一个硬链接,则事实上就是彻底删除该文件。

Fs.unlink(srcpath,callback);

Callback = function(err){…}

同步方法: fs.unlinkSync(srcpath)

2.5.4 创建和查看符号链接(符号链接又叫软链接)

符号链接(软链接):在操作系统中,可以为文件或目录创建一个或多个符号链接。所谓符号链接,是一种特殊的文件,这个文件中仅包含了另一个文件或目录的路径及文件名或目录名。如果打开一个文件的符号链接文件进行编辑,操作系统将自动打开符号链接中所指向的原文件进行编辑,如果打开一个目录的符号链接文件进行文件的创建,编辑或删除文件,则操作系统将自动打开符号链接中所指向的原目录进行相应的操作。如果删除符号链接文件,不会删除元文件或目录,如果删除或移动原文件或目录,符号链接文件也不会删除,这时会产生一种称为“断链”现象。

Fs.symlink(srcpath,dstpath,[type],callback);

Callback = function(err){…}

参数:srcpath参数用于指定需要被创建符号链接的文件或目录的完整路径及文件或目录名,detpath参数用于指定被创建的符号链接的完整路径及文件名或者目录名;type参数用于指定为文件创建符号链接还是为目录创建符号链接,可指定的值为file(为文件创建符号链接),dir(为目录创建符号链接,在非windows系统中只能使用dir参数值)以及junction(为目录创建符号链接,只在windows操作系统中有效),默认值为file。

同步方法:fs.symlinkSync(srcpath,dstpath,[type])

2.5.5 在创建一个符号链接之后,可以使用fs模块中的readlink方法读取符号链接中所包含的另一个文件或者美丽的路径及文件名或目录名。

Fs.readlink(path,callback);

Callback = function(err,linkString){…}

参数:path参数用于指定符号链接的路径及文件名或目录名。linkString参数值为读取到的一个链接字符串,其中包含了另一个文件或目录的路径及文件名或目录名。

同步方法:var linkString = fs.readlinkSync(path);

2.5.6截断文件

在fs模块中,可以使用truncate方法对文件进行截断操作(所谓对文件进行截断操作就是指一种首先清除文件内容,然后修改文件尺寸的操作).

Fs.truncate(filename,len,callback);

Callback = function(err){…}

参数:filename参数用于指定需要被截断文件的完整文件路径及文件名,len参数值为一个整数,用于指定被截断后的文件尺寸(以字节为单位)。

同步方法: fs.truncateSync(filename,len)

2.5.7 在使用open或openSync方法打开文件并返回文件描述符后,可以使用fs模块中的ftruncate方法截断文件,

Fs.ftruncate(fd,len,callback);

同步方法: fs.ftruncateSync(fd,len);

2.5.8 删除空目录

Fs.rmdir(path,callback); fs.rmdirSync(path)

2.5.9 监视文件或目录

2.5.9.1  可以使用watchFile方法对文件进行监视,并且在监视到文件被修改时执行某些操作,该方法使用方式如下:

Fs.watchFile(filename,[options],listener)

可以使用多个watchfile方法对同一个文件进行监视,并且在各自watchFile方法的回调函数中书写当文件发生改变时需要执行的不同处理。

Listener = function(curr,prev){…}

参数:filename参数用于指定需要被监视的文件的完整路径及文件名。options参数值为一个对象,persistent属性来指定当指定了被监视的文件后是否停止当前正在运行的应用程序,该属性值默认值为true(应用程序不会立即退出);interval属性值来指定每隔多少毫秒监视一次文件是否发生改变。回调函数参数:curr参数值为一个fs.stats对象,代表被修改之后的当前文件,prev参数值为一个fs.stats对象,代表被修改之前的当前文件。

备注:如果一个文件没有被创建,curr,prev返回的对象中ctime,mtime,atime都为“ 1970-01-01T00:00:00.000Z”,这个时间是计算机启用时间毫米数。(1).当一个文件在没有被创建时,Date.parse(curr.ctime),Date.parse(curr.atime),Date.parse(curr.mtime)都为0,(2).当创建一个文件之后Date.parse(curr.ctime)不为0,(3).当Date.parse(curr.ctime) != Date.parse(curr.mtime)表示该文件被修改过。

2.5.9.2当使用watchFile方法对文件进行监视后,可以使用unwatchFile方法取消当文件发生改变时所要执行的处理

Fs.unwatchFile(filename,[listener])

参数:filename参数用于指定需要被取消处理的文件完整路径及文件名,listener参数值为使用watchFile方法监视文件时调用的某个回调函数,用于指定当文件发生改变时需要取消哪个回调函数中所指定的处理,如果不指定该参数值,则取消对该文件的监视。

2.5.9.3 在fs模块中,可以使用watch方法对文件或目录进行监视,并且在监视到文件或目录被修改时执行某些操作。

Fs.watch(filename,[options],[listener]);

Listener = function(event,filename){…}

参数:filename参数用于指定需要被监视的文件或目录的完整路径及文件名或目录名,options参数值为一个对象,persistent属性来指定当指定了被监视的文件后是否停止当前正在运行的应用程序,该属性值默认值为true(应用程序不会立即退出),listener参数值为一个回调函数,指定当被监视的文件或目录发生改变时调用的回调函数。回调函数参数值:event, 当event参数值为’rename’(当被制定的文件或被制定的目录中的任何文件被重命名,移动或者删除),event参数值为’change’(当被指定的文件或被指定的目录中的任何文件内容发生改变时),filename参数值为任何发生改变的文件(可以是被指定的文件,也可以是被指定的目录中任何发生改变的文件)的完整路径及文件名。

Fs.watch()方法返回一个fs.FSWatch对象,该对象拥有一个close方法,用于停止对 watch方法中指定监视的文件或者目录所执行的监视操作。

Var watcher = fs.watch(filename,[options],[listener]);

Watcher.close();

使用watch方法指定监视的文件或者目录发生改变时,触发fs.FSWatch对象的change事件,该事件触发时可以调用的回调函数的指定方法如下所示:

function(event,filename){….}

例如: watcher.on(‘change’,function(event,filename){…})

使用watch方法指定监视的文件或目录进行监视的过程中发生错误时,触发fs.FSWatch对象的error事件,该事件触发时可以调用的回调函数function(error){…}

例如:watch.on(‘error’,function(error){…})

3. 使用流文件

3.1回顾:fs模块中几种文件读写方法的区别

用途

使用异步方式

使用同步方式

将文件完整读入缓冲区

readFile

readFileSync

将文件部分读入缓冲区

read

readSync

将数据完整写入文件

writeFile

writeFileSync

将缓冲区中部分文件写入文件

write

writeSync

如表所示:在使用readFile或readFileSync方法读取内容时,node.js首先将文件内容完整地读入缓冲区中,再从该缓冲区中读取文件内容。在使用writeFile或者writeFileSync方法写入文件时,node.js首先将该文件内容完整读入缓冲区,然后一次性将缓冲区中内容写入文件。也就是说,使用readFile或readFileSync方法读取文件内容或使用writeFile或writleFileSync方法写入文件内容时,node.js将该文件内容视为一个整体,为其分配缓冲区并且一次性将文件内容读取到缓冲区中,在这个期间,node.js将不能执行其他操作。

在使用read或readSync方法读取文件内容时,node.js将不断地文件中一小内容读入缓冲区,最 后从该缓冲区中读取文件内容。如果使用write或writeSync方法写入文件内容,node.js将执行一下过程:① 将需要书写的数据写到一个缓冲区,②待缓冲区写满后再将该缓冲区中内容写入到文件中,   ③重复执行过程① 与过程②,直到数据全部写入文件为止。也就是说,如果使用read或readSync方法读取文件内容或者使用write或writeSync方法写入文件时,在读写文件过程中允许node.js执行其他处理。

3.2 流是一组有序的,有起点和终点的字节数据的传输手段。在应用程序中各种对象之间交换与传输数据的时候,总是先将该对象所包含的数据转换为各种形式的流数据(即字节数据),再通过流的传输,到达目的对象后再将流数据转换为该对象中可以使用的数据。

3.2.1 使用readStream对象读取文件

读取数据的对象将触发的事件:readable,data,end,error,close

读取数据的对象所拥有的方法:

方法名

Read

用于读取数据

setEncoding

用于指定用什么编码方式读取数据

pause

用于通知对象停止触发data事件

resume

用于通知对象恢复触发data事件

pipe

用于设置一个数据通道,然后所有流数据并将其输出到通道另一端所指向的目标对象中。

Unpipe

用于取消在pipe方法中设置的通道

Unshift

当对数据流绑定了一个解析器时,可以使用unshift方法来取消该解析器的绑定,使流数据可以通过其他方式来解析

Fs.createReadStream(path,[options]);

参数:path参数用于指定需要被读取的文件完整路径及文件名。options参数为一个对象,该对象具有如下属性:

  • ★flags:用于指定对该文件采取什么操作,默认值为’r’,可指定属性值与readFile方法中所使用options参数对象中所使用的flags属性可指定的属性值相同。
  • ★encodeing编码格式,utf8,ascii,base64,默认值为null
  • ★autoClose用于指定是否关闭在读取文件时操作系统内容使用的文件描述符。如果属性值设定为false,则不会自动关闭,即使在读取文件过程中产生了错误,开发者必须通过使用close或closeSync方法来手动关闭文件。如果属性值设定为true,当文件读取完毕或读取过程中产生错误时文件将自动关闭。autoClose属性值默认值为true。
  • ★Start:使用整数来指定文件开始读取位置。
  • ★End:使用整数来指定文件结束读取位置。

例: 常规读取文件实例

Var file = fs.createReadStream(‘./other.txt’,{start:3,end:12});

File.on(‘open’,function(fd){…}) fd文件描述符

File.on(‘data’,function(data){…}) data读取到的文件内容

File.on(‘end’,function(){…})

File.on(‘close’,function(){…})

File.on(‘error’,function(err){…}) err读取失败时,错误返回码

3.2.2 使用writeStream对象写入文件

Fs.createWriteStream(path,[options])

参数:同上,start:使用整数来指定文件开始写入位置(单位为字节书)。如果要在文件中追加写入数据,需要将flags属性值设置为’a’.

writeStream对象具有一个write方法,用于将流数据写入到目标对象中,

  • ★Writable.write(chunk,[encoding],[callback]

参数:chunk为一个buffer对象或一个字符串,用于指定需要写入的数据,当参数值为buffer对象时表示将buffer对象写入目标数据中,当参数值为字符串时,表示将字符串写入目标数据中。

备注:当操作系统缓冲区中数据已全部写满时,该参数值为false,表示操作系统缓冲区中的数据已满并将立即输出到目标对象中,当操作系统缓冲区中还可以写入数据时,该参数值返回true。在node.js中,当操作系统缓冲区中数据已写满时,不代表不能写入数据,而是指在将操纵系统缓冲区中的数据写入到文件的同时把读取到的数据暂时缓存在内存中,待操作系统缓冲区中的数据已被全部读出写入到目标文件中,触发writeStream对象的drain事件,表示操作系统缓冲区中的数据已全部读出,可以继续向操作系统缓冲区中写入新的数据。

  • ★WriteStream对象的write方法返回一个布尔类型的返回值,当操作系统缓冲区中数据已全部写满时,该参数值为false。当操作系统缓冲区中还没有写满数据时,该参数值返回true。
  • ★WriteStream对象具有一个end方法,在写入文件的场合中,当没有数据再被写入流中时,可调用该方法关闭文件。这将迫使操作系统缓冲区中的剩余数据被立即写入文件中。可以使用在该方法的回调函数中指定文件被关闭之前所要执行的操作。

Writeable.end([chunk],[encoding],[callback])

参数: chunk参数值可以为一个buffer或一个字符串,用于指定在文件关闭之前需要在文件中追加写入的数据。

  • ★WriteStream对象具有一个bytesWritten属性,属性值为当前已在文件中写入数据的字节数。

例:var writeable = fs.createWriteStream(“./other.txt”);

Writeable.bytesWritten (字节数)。

在读取一个尺寸较大的文件时,操作系统将执行以下操作:

①首先读取该文件中的 数据并把输入填入操作系统缓冲区,直到填满为止。

②不断执行把缓冲区中数据写入目标文件,同时读取文件中剩余数据并把数据填入内存的操作,这时控制台中不断显示write方法的执行结果为false(代表操作系统缓冲区已满)。

③待操作系统缓冲区中数据已全部被写入目标文件时,触发一次drain事件,在控制台中输出“操作系统缓冲区中的数据已全部输出”的字符串。

④首先将内存的数据写入到操作系统缓冲区中,然后读取文件中的剩余数据并填入缓冲区,一直到填满为止。

⑤重复执行②③④

3.2.3 我们也可以使用readStream对象的pipe方法执行文件的复制操作(readStream代表一个readStream对象)

readStream.pipe(destination,[options])

readStream.unpipe([destination])

参数:destination参数值必须为一个可用于写入流数据的对象,在写文件时为需要被写入的文件的完整路径及文件名,options为一个对象,可以在该对象中使用一个布尔类型的end属性,如果属性为true,则当数据被全部读取完毕时,立即将操作系统缓冲区中剩余的数据全部写入文件中并关闭文件;如果为false,则并不关闭文件,文件中可以继续写入新的数据,该属性的默认值为true