- fs模块下的类与FS常量
- fs模块下的主要方法
- fs的Promise API与FileHandle类
一、fs模块下的类
1.1 fs.Dir:表示目录流的类,由 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
创建。
1.2 fs.Dirent:目录项的表现形式,通过从fs.Dir中读取返回。
1.3 fs.FSWatcher:继承自 <EventEmitter>,调用 fs.watch()
方法返回该对象。每当指定监视的文件被修改时,所有的 fs.FSWatcher
对象都会触发 ‘change‘
事件。
1.4 fs.ReadStream
:成功调用 fs.createReadStream()
将会返回一个新的 fs.ReadStream
对象。用于读取流。
1.5 fs.Stats:文件信息对象。从 fs.stat()
、fs.lstat()
和 fs.fstat()
及其同步的方法返回的对象都属于此类型。
1.6 fs.WriteStream:继承自 <stream.Writable>,管理文件写入流。
1.7 FS常量:
1.7.1文件可访问性,用于fs.access():
F_OK :表明文件对调用进程可见。可以用来判断文件是否存在,但没有有rwx权限说明。
R_OK :表明调用进程可以读取文件。
W_OK :表明调用进程可以写入文件。
X_OK :表明调用进程可以执行文件。在window系统上无效,表现的像fs.constants.F_OK。
1.7.2文件拷贝常量,用于fs.copyFile()。
COPYFILE_EXCL :如果目标路径已经存在,则拷贝操作将失败。
COPYFILE_FICLONE :拷贝操作将尝试创建写时拷贝连接。如果底层平台不支持写时拷贝,则使用备选拷贝机制。
COPYFILE_FICLONE_FORCE :拷贝操作将尝试创建写时拷贝连接。如果底层平台不支持写时拷贝,则拷贝失败。
1.7.3文件打开的常量,用于fs.open()。
O_RDONLY :表明打开文件用于只读访问。 O_WRONLY :表明打开文件用于只写访问。 O_RDWR :表明打开文件用于读写操作。 O_CREAT :表明如果文件不存在则创建文件。 O_EXCL :表明如果设置了O_CREAT标志且文件已存在,则打开文件应该失败。 O_NOCTTY :表明如果路径表示中断设备,则打开该路径不应该造成该终端变成进程的控制终端(如果进程还没有终端)。 O_TRUNC :表明如果文件存在且是常规文件、并且文件成功打开以进行写入访问,且长度应截断为零。 O_APPEND :表明数据将会追加到文件的末尾。 O_DIRECTORY :表明如果路径不是目录,则打开应该失败。 O_NOATIME :表明文件系统的读取访问不再导致于文件相关联的atime信息的更新。仅在Linux系统上有效。 O_NOFOLLOW :表明如果路径是符号连接,则打开应该失败。 O_SYNC :表明文件是为同步I/O打开的,写入操作将会等待文件的完整性。 O_DSYNC :表明文件是为同步I/O打开的,写入操作将会等待数据的完整性。 O_SYMLINK :表明打开符号连接自身,而不是它指向的资源。 O_DIRECT :表明将尝试最小化文件I/O的缓冲效果。 O_NONBLOCK :表明在可能的情况下以非阻塞模式打开文件。 UV_FS_O_FILEMAP :当设置后,将会使用内存文件的映射来范文文件。此标志仅在windows系统上有效,其它系统此标志会被忽略。
1.7.4文件类型的常量,用于fs.Stats对象的mode属性,用于决定文件的类型。
S_IFMT :用于提取文件类型代码的位掩码。
S_IFREG :表示常规文件。
S_IFDIR :表示目录。
S_IFCHR :表示面向字符的设备文件。
S_IFBLK :表示面向块的设备文件。
S_IFIFO :表示FIFO或管道。
S_IFLNK :表示符号连接。
S_IFSOCK :表示套接字。
1.7.5文件模式常量,用于fs.Stats对象的mode属性,用于决定文件的访问权限。
S_IRWXU :表明所有者可读、可写、可执行。
S_IRUSE :表明所有者可读。
S_IWUSR :表明所有者可写。
S_IXUSR :表明所有者可执行。
S_IRWXG :表明群组可读、可写、可执行。
S_IRGRP :表明群组可读。
S_IWGRP :表明群组可写。
S_IXGRP : 表明群组可执行。
S_IRWXO :表明群组可读、可写、可执行。
S_IROTH :表明其他人可读。
S_IWOTH :表明其他人可写。
S_IXOTH :表明其他人可执行。
1.8 FS文件系统标志(flag):
a 可写、可创建、可追加。(组合标志: a+、ax、as)
——a标志用来追加写入,如果没有该文件会创建该文件。
r 可读。(组合标志:r+、rs 、rs+)
——r标志用来读取文件,如果没有该文件会抛出异常。
w 可写、可创建。(组合标志:w+、wx、wx+)
——w标志用来做写入操作,如果没有该文件则创建,如果有该文件则截断。
——x标志用来表示文件可执行。
——s表示同步阻塞的方式操作文件。
1.9 FS文件操作权限:
文件操作权限分为三个等级:文件所有者权限、同组用户的权限、非同组用户的权限。每组权限都用一个数值表示,该数值是由标志转换加和而来(r对应4;w对应2;x对应1)。
比如在fs.open(path[, flags[, mode]], callback)用来设置用户权限的是mode参数,该参数默认操作权限是:0o666。0o表示后面的数值为8进制,666按顺序分别对应:所有者、同组用户、非同组用户。所以这个默认参数所表示的是所有用户都具备可读、可写的权限。
二、fs模块下的主要方法
2.1 FS.access():测试用户对Path指定的文件或目录的权限。
fs.access(path[,mode],callback);//异步:回调函数调用时将传入可能的错误参数,如果权限检查通过就不会传入参数。 fs.accessSync(path[,mode]);//同步:如果权限检查不通过则抛出Error。否则通过的话就返回undefined。
可以使用access检查文件是否存在(F_OK)、文件是否可读(R_OK)、文件是否可写(W_OK)、文件是否可执行(X_OK)。注意windows下“X_OK”无效。
不建议在fs.open()、fs.readFile()、fs.writeFile()【打开文件、读取文件、写入文件】之前使用access,相反这些操作建议直接进行,不必要在操作之前进行检查,以免引发竞态。
1 const file = ‘package.json‘; 2 3 // 检查当前目录中是否存在该文件。 4 fs.access(file, fs.constants.F_OK, (err) => { 5 console.log(`${file} ${err ? ‘不存在‘ : ‘存在‘}`); 6 }); 7 8 // 检查文件是否可读。 9 fs.access(file, fs.constants.R_OK, (err) => { 10 console.log(`${file} ${err ? ‘不可读‘ : ‘可读‘}`); 11 }); 12 13 // 检查文件是否可写。 14 fs.access(file, fs.constants.W_OK, (err) => { 15 console.log(`${file} ${err ? ‘不可写‘ : ‘可写‘}`); 16 }); 17 18 // 检查当前目录中是否存在该文件,以及该文件是否可写。 19 fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => { 20 if (err) { 21 console.error( 22 `${file} ${err.code === ‘ENOENT‘ ? ‘不存在‘ : ‘只可读‘}`); 23 } else { 24 console.log(`${file} 存在,且它是可写的`); 25 } 26 }); 27 28 //同步检查 29 try { 30 fs.accessSync(‘etc/passwd‘, fs.constants.R_OK | fs.constants.W_OK); 31 console.log(‘可以读写‘); 32 } catch (err) { 33 console.error(‘无权访问‘); 34 }
2.2 FS.appendFile():将数据追加到文件,如果文件不存在则创建文件。
fs.appendFile(path, data[, options], callback);//异步:options可以配置文件encoding、mode、flag【字符编码、权限值、文件可操作标志符】,如果写入一个字符串值只表示字符编码。 //callbakc:当操作不可操作时会传入error对象 fs.appendFileSync(path,data[,options]);//同步
path可以指定为已打开的文件的数字型文件描述符,用于追加文件数据。
1 //为指定路径的文件追加数据 2 fs.appendFile(‘message.txt‘, ‘追加的数据‘, (err) => { 3 if (err) throw err; 4 console.log(‘数据已追加到文件‘); 5 }); 6 //paht为已打开的文件数字型文件描述符(fd) 7 fs.open(‘message.txt‘, ‘a‘, (err, fd) => { 8 if (err) throw err; 9 fs.appendFile(fd, ‘追加的数据‘, ‘utf8‘, (err) => { 10 fs.close(fd, (err) => { 11 if (err) throw err; 12 }); 13 if (err) throw err; 14 }); 15 }); 16 17 //同步示例一 18 try { 19 fs.appendFileSync(‘message.txt‘, ‘追加的数据‘); 20 console.log(‘数据已追加到文件‘); 21 } catch (err) { 22 /* 处理错误 */ 23 } 24 //同步示例二 25 let fd; 26 try { 27 fd = fs.openSync(‘message.txt‘, ‘a‘); 28 fs.appendFileSync(fd, ‘追加的数据‘, ‘utf8‘); 29 } catch (err) { 30 /* 处理错误 */ 31 } finally { 32 if (fd !== undefined) 33 fs.closeSync(fd); 34 }
2.3 Fs.chmod():修改文件权限。
fs.chmod(path,mode,callback);//异步:回调函数除了可能的异常对象,没有其他参数。 fs.chmodSync(path,mode);//同步
关于权限设置的mode参数值详细可参考第一节中的1.8和1.9的内容。
1 fs.chmod(‘my_file.txt‘, 0o775, (err) => { 2 if (err) throw err; 3 console.log(‘文件 “my_file.txt” 的权限已被更改‘); 4 });
2.4Fs.chown():更改文件所有者和群组。
fs.chown(path,uid,gid,callback);//异步:uid-所有者id、gid-群组id fs.chownSync(path,uid,gid);//同步
2.5FS.close():关闭文件,与此对应的是打开文件方法open()。
fs.close(fd,callback);//异步 fs.closeSync(fd);//同步
2.6Fs.constants:返回包文件系统操作常用常量的对象。
详细内容见第一节1.7。
2.8Fs.copyFile():拷贝文件。
fs.copyFile(src,dest[,flags],callback);//异步 //src:要拷贝的文件 //dest:拷贝操作的目标文件名 //flags:用于拷贝操作修饰符,详细见第一节1.7.2 //callback:除了可能发生的错误err对象没有其他参数 fs.copyFileSync(src,dest[,flags])
1 //示例一 2 const fs = require(‘fs‘); 3 4 // 默认情况下将创建或覆盖目标文件。 5 fs.copyFile(‘源文件.txt‘, ‘目标文件.txt‘, (err) => { 6 if (err) throw err; 7 console.log(‘源文件已拷贝到目标文件‘); 8 }); 9 //示例二 10 const fs = require(‘fs‘); 11 const { COPYFILE_EXCL } = fs.constants; 12 13 // 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。 14 fs.copyFile(‘源文件.txt‘, ‘目标文件.txt‘, COPYFILE_EXCL, callback);
2.9Fs.createReadStream(path[,options]):创建一个读取文件流对象 <fs.ReadStream>。
path <string> | <Buffer> | <URL> options <string> | <Object> //当optiions为一个字符串时表示字符编码 //当options为对象时可以包含以下字段: flags--文件标志 encoding--字符编码 fd--文件描述符(指向仅支持阻塞读取的字符设备) mode--文件权限 autoClose--默认:true,在error或end事件时关闭文件描述符。当属性值为false时即使出现错误,文件描述符也不会关闭。应用程序需要关闭文件描述符来确保没有文件描述符泄露。 emitClose--默认:false,流在销毁后不会触发‘close’事件。当属性值为true改变此行为。 start--与end配合读取文件的范围。 end--默认:Infinity highWaterMark--默认:64*1024
2.10Fs.createWriteStream(path[, options]):创建一个写入流对象<fs.WriteStream>。
path <string> | <Buffer> | <URL> options <string> | <Object> //当options为字符串时,该值为字符编码。 //当options为对象时: flags--文件标志符 encoding--字符编码 fd--文件描述符 mode--文件权限 autoClose--默认true,当error或finish事件是文件描述符自动关闭。为false时即使出错文件描述符也不关闭。 emitClose--默认false,流在注销时不会触发close事件,反之则出发。 start--允许再文件开头之后的某个位置写入数据
2.11Fs.existsSync(path):判断文件路径是否存在(同步,对应的异步方法已废弃)。
//如果路径存在,则返回 true,否则返回 false。 //示例: if (fs.existsSync(‘/etc/passwd‘)) { console.log(‘文件已存在‘); }
2.12Fs.fchmod():修改文件权限。
fs.fchmod(fd,mode,callback);//异步修改文件权限 fs.fchmodSync(fd,mode);//同步修改文件权限 //fd--文件描述符;mode--权限(0o666);callback除了可能出现的error对象没有其他参数
2.13Fs.fchown():修改文件所有者和群组。
fs.fchown(fd,uid,gid,callback);//异步修改文件所有者和群组 fs.fchownSync(fd,uid,gid);//同步修改文件所有者和群组 //fd--文件描述符;uid--所有者id;gid--群组id;callback除了出现可能的异常传入error参数以外不需要传入其他参数
2.14Fs.fdatasync():文件数据同步
fs.fdatasync(fd,callback);//异步 fs.fdatasyncSync(fd);//同步
2.15Fs.fstat():生成文件信息对象fs.Stats
。
fs.fstat(fd[,options],callback);//异步:optiosn只有一个bigint<boolean>字段,默认为false,意思是生成普通fs.stats对象,否则生成BigintStats对象 fs.fstatSync(fd,[options]);//同步
2.16Fs.fsync():文件同步
fs.fsync(fd,callback);//异步实现文件同步 fs.fssyncSync(fd);//同步实现文件同步
2.17Fs.ftruncate():截断文件
fs.ftruncate(fd[, len], callback);//异步 fs.ftruncateSync(fd[,len]);//同步
如果文件描述符指向的文件大于 len 个字节,则只有前面 len 个字节会保留在文件中。
1 //示例一 2 console.log(fs.readFileSync(‘temp.txt‘, ‘utf8‘)); 3 // 打印: Node.js 4 5 // 获取要截断的文件的文件描述符。 6 const fd = fs.openSync(‘temp.txt‘, ‘r+‘); 7 8 // 将文件截断为前 4 个字节。 9 fs.ftruncate(fd, 4, (err) => { 10 assert.ifError(err); 11 console.log(fs.readFileSync(‘temp.txt‘, ‘utf8‘)); 12 }); 13 // 打印: Node 14 15 //示例二 16 console.log(fs.readFileSync(‘temp.txt‘, ‘utf8‘)); 17 // 打印: Node.js 18 19 // 获取要截断的文件的文件描述符。 20 const fd = fs.openSync(‘temp.txt‘, ‘r+‘); 21 22 // 将文件截断为前 10 个字节,但实际大小为 7 个字节。 23 fs.ftruncate(fd, 10, (err) => { 24 assert.ifError(err); 25 console.log(fs.readFileSync(‘temp.txt‘)); 26 }); 27 // 打印: <Buffer 4e 6f 64 65 2e 6a 73 00 00 00> 28 // (UTF8 的值为 ‘Node.js\0\0\0‘)
2.18Fs.futimes():更改文件的时间戳
fs.futimes(fd, atime, mtime, callback);//异步 fs.futimesSync(fd, atime, mtime)//同步
2.19Fs.lchmod():修改文件权限。
fs.lchmod(path, mode, callback);//异步:只适应macOS fs.lchmodSync(path, mode)//同步
2.20Fs.lchown():修改文件所有者与群组
fs.lchown(path, uid, gid, callback);//异步 fs.lchownSync(path, uid, gid);//同步
2.21Fs.link():给文件创建新的连接
fs.link(existingPath, newPath, callback);//异步 fs.linkSync(existingPath, newPath);//同步
2.22Fs.lstat():生成文件信息对象。
fs.lstat(path[, options], callback);//异步 fs.lstatSync(path[, options]);//同步
2.23Fs.mkdir():创建目录。
fs.mkdir(path[, options], callback);//异步 fs.mkdirSync(path[, options]);//同步
options包含两个字段:recursive<boolean>是否创建父级对象。mode配置文件权限(在windows上无效)
1 // 创建 /tmp/a/apple 目录,无论是否存在 /tmp 和 /tmp/a 目录。 2 fs.mkdir(‘/tmp/a/apple‘, { recursive: true }, (err) => { 3 if (err) throw err; 4 });
2.24Fs.mkdtemp():创建唯一的临时目录。
fs.mkdtemp(prefix[, options], callback);//异步 fs.mkdtempSync(prefix[, options]);//同步
prefix(文件夹名称不要以x结尾);options<string | object>为一个字符串时直接表示字符编码,为对象时也只有一个encoding(字符编码)字段。
1 //示例一 2 fs.mkdtemp(path.join(os.tmpdir(), ‘目录-‘), (err, folder) => { 3 if (err) throw err; 4 console.log(folder); 5 // 打印: /tmp/目录-itXde2 或 C:\Users\...\AppData\Local\Temp\目录-itXde2 6 }); 7 8 //示例二 9 // 新的临时目录的父目录。 10 const tmpDir = os.tmpdir(); 11 12 // 此用法是错误的: 13 fs.mkdtemp(tmpDir, (err, folder) => { 14 if (err) throw err; 15 console.log(folder); 16 // 输出类似 `/tmpabc123`。 17 // 新的临时目录会被创建在文件系统根目录,而不是在 /tmp 目录中。 18 }); 19 20 // 此用法是正确的: 21 const { sep } = require(‘path‘); 22 fs.mkdtemp(`${tmpDir}${sep}`, (err, folder) => { 23 if (err) throw err; 24 console.log(folder); 25 // 输出类似 `/tmp/abc123`。 26 // 新的临时目录会被创建在 /tmp 目录中。 27 });
2.25Fs.open():用于打开文件。
fs.open(path[, flags[, mode]], callback);//异步打开文件:回调函数的参数(err,fd) fs.openSync(path[, flags, mode]);//同步打开文件:返回文件描述符fd
如果文件标志flags设置了可写,当打开文件不存在时会自动创建该文件。
2.26Fs.opendir():用于打开文件夹(目录)。
fs.opendir(path[, options], callback);//异步打开文件夹,回调函数的参数(err,dir),dir一个文件目录流对象(fs.dir对象) fs.opendirSync(path[, options]);//同步打开文件夹:返回fs.dir
2.27Fs.read():用于读取文件。
fs.read(fd, buffer, offset, length, position, callback);//异步读取。
fs.readSync(fd, buffer, offset, length, position);//同步读取。返回 bytesRead<number>
的数量。
//fd--文件描述符
//buffer--数据将写入缓冲区
//offset--buffer写入的偏移量
//length--指定读取的字节数
//position--指定开始读取的位置
//callback--三个参数:err、bytesRead、buffer
2.28Fs.readdir():用于读取目录内容。
fs.readdir(path[, options], callback);//异步:回调函数有两个参数(err,files) fs.readdirSync(path[, options]);//同步:返回文件名数组
读取的结果为文件名数组,如果options参数中的withFileTypes设置为true则 files 数组将包含 fs.Dirent 对象。
options参数还可以有一个字符编码字段encoding,除了设置字符编码值还可以设置为buffer,读取的文件名数组就是buffer对象。
2.29Fs.readFile():读取文件。
fs.readFile(path[, options], callback);//异步 fs.readFileSync(path[, options]);//同步:返回文件内容data<string>|<buffer> //path <string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。如果将文件描述符指定为 path,则不会自动关闭它。 //options:{encoding,flag}任何指定的文件描述符都必须支持读取。 //callback(err,data)--data<string>|<buffer>
2.30Fs.readlink():读取文件连接。
fs.readlink(path[, options], callback);//异步 fs.readlinkSync(path[, options]);//同步 //path--<string> | <Buffer> | <URL> //options--<string>|<object> :encoding--默认‘utf8’,该值可设置为‘buffer’ //callback(err,linkstring);//当设置encoding为buffer时,文件连接将作为buffer类型,否则为string类型
2.31Fs.realpath():通过解析“.”、“..”计算规范路径。不同系统环境返回值会有差异。
fs.realpath(path[, options], callback);//异步 fs.realpathSync(path[, options]);//同步 //path--相对路径 //options--字符编码<string>|<object>:{encoding} //callback(err,resolvedPath);resolvedPath--绝对路径
规范路径名不一定是唯一的。 硬链接和绑定装载可以通过许多路径名暴露文件系统实体。
此函数的行为类似于 realpath(3),但有一些例外
1.在不区分大小写的文件系统上不执行大小写转换。。
2.符号链接的最大数量与平台无关,并且通常高于本地 realpath(3) 实现支持的数量。
callback 有两个参数 (err, resolvedPath)。 可以使用 process.cwd 来解析相对路径。
仅支持可转换为 UTF8 字符串的路径。
1 function rePath(pathName) { 2 fs.realpath("./fs/"+pathName + ".txt", ‘utf8‘, function(err,resolvedPath){ 3 if(err) throw err; 4 console.log(resolvedPath); 5 }); 6 }
2.32Fs.realpath.native():同realpath基本一致。
fs.realpath.native(path[, options], callback);//异步 fs.realpathSync.native(path[, options]);//同步 //在 Linux 上,当 Node.js 与 musl libc 链接时,procfs 文件系统必须挂载在 /proc 上才能使此功能正常工作。 Glibc 没有这个限制。
2.33Fs.rename():使用新的路径名称替换文件原来的路径名称,相当于文件剪切+重命名操作。
fs.rename(oldPath, newPath, callback);//异步 fs.renameSync(oldPath, newPath);//同步 //异步地将 oldPath 上的文件重命名为 newPath 提供的路径名。 如果 newPath 已存在,则覆盖它。
1 function rename(pathName){ 2 fs.rename("./fs/"+pathName + ".txt","rename.txt",function (err) { 3 if(err) throw err; 4 console.log("重命名完成"); 5 }) 6 }
2.34 Fs.rmdir():用来删除文件夹。
fs.rmdir(path[, options], callback);//异步 fs.rmdirSync(path[, options]);//同步 //path--文件夹路径 //options--{emfileWait,maxBusyTries,recursive} //emfileWait--如果发生错误,以1毫秒的频率进行回退,重试操作。该参数默认值1000毫秒,如果在这个设定的时间内重试不成功则抛出错误。 //maxBusyTries--以100毫秒为频率进行回退,重试操作。该操作默认值3,表示重试操作3次。 //recursive--如果设置为true,则执行递归删除目录,如果path不存在不抛出错误,重试该操作,知道超出重试时间或次数。 //--只能删除空文件夹
2.35Fs.stat():生成文件信息对象fs.stats。
fs.stat(path[, options], callback);//异步 fs.statSync(path[, options]);//同步--返回fs.stats //options<object>{bigint}--bigint返回的 fs.Stats 对象中的数值是否应为 bigint 型。默认值: false。 //callback(err,stats)
2.36Fs.symlink():创建一个链接指向文件或目录。
fs.symlink(target, path[, type], callback);//异步 fs.symlinkSync(target, path[, type]);//同步 //target--目标文件或目录 //path--链接 //type--仅在windows上有用,用来指定文件类型(dir、file、junction),如果找到指定的类型则使用file类型。 //callback(err)
2.37Fs.truncate():截断文件内容。
fs.truncate(path[, len], callback);//异步callback(err) fs.unlink(path, callback);//同步--返回undefined //len--指定截取文件内容的字节数,从文件内容起始位置到len。(默认参数为0,表示截取文件所有内容) //这个方法尽量不要使用fd(文件描述符)可能导致出错,尽量使用文件路径作为path,使用fd的操作可以使用fs.ftruncate()
2.38Fs.unlink():删除文件
fs.unlink(path, callback);//异步:callback(err) fs.unlinkSync(path);//同步--返回undefined //path--可使用路径字符串,也可以使用fd文件描述符
2.39Fs.unwatchFile():删除文件上指定的事件监听器。
fs.unwatchFile(filename[, listener]); //filename--文件名称 //listener--监听器名称
2.40Fs.utimes():更改指定的文件或文件夹的文件系统时间戳。
fs.utimes(path, atime, mtime, callback);//callback(err) fs.utimesSync(path, atime, mtime) //path--文件、文件夹 //atime--Unix纪元时间的数字值、Date对象、或类似 ‘123456789.0‘ 的数值字符串。 //mtime--时间戳
2.41Fs.watch():给文件设置更改时的事件监听器。
fs.watch(filename[, options][, listener]); //filename--监听的文件或目录 //options<string>|object--{persistent,recursive}--persistent指示文件已被监听,进程是否继续运行;recursive--指示应该监听所有子目录还是监听当前目录。 //listener(eventType,filename)--监听器回调函数 //eventType--事件类型‘rename‘、‘change‘ //filename--触发事件的文件名称
fs.watch不是所有平台都兼容的API,仅在macOS和windows上支持。
- 在 Linux 系统上,使用
inotify(7)
。 - 在 BSD 系统上,使用
kqueue(2)
。 - 在 macOS 系统上,对文件使用
kqueue(2)
,对目录使用FSEvents
。 - 在 SunOS 系统上(包括 Solaris 和 SmartOS),使用事件端口。
- 在 Windows 系统上,此特性取决于
ReadDirectoryChangesW
。 - 在 Aix 系统上,此特性取决于
AHAFS
必须启动。
2.42Fs.watchFile():监视 filename
的更改。 每当访问文件时都会调用 listener
回调。
fs.watchFile(filename[, options], listener);//该方法与fs.watch()非常类是,watch()用于设置文件和目录的监听事件;但watchFile只能设置文件的监听事件 //filename--文件名称 //options<object>--{persistent,interval}--persistent:指示文件正在被监视,进程是否应该继续运行;interval指示目录轮询频率 //listener(current,previous) //current--当前最近修改的记录对象:比如修改的时间curent.mtime //previous--之前最近修改的记录对象
当 fs.watchFile()
正在监视的文件消失并重新出现时,第二次回调事件(文件重新出现)返回的 previousStat
会与第一次回调事件(文件消失)返回的 previousStat
相同。
这种情况发生在:
- 文件被删除,然后又恢复。
- 文件被重命名,然后再第二次重命名回其原来的名称。
2.43Fs.write():将数据写入到指定位置。(如果不指定位置会覆盖之前的数据从最开始的位置写入)
fs.write(fd, string[, position[, encoding]], callback)//异步 fs.writeSync(fd, buffer[, offset[, length[, position]]])//同步--返回一个nummber值,表示写入的字节数 //fd--文件描述符 //string--数据。如果string不是一个字符串,会被强制转换成字符串。 //position--指定文件开头的偏移量(数据应该写入的位置)。如果position不是number原始类型则从最开始的位置写入。 //encoding--string【数据】期望的字符串编码。 //callback(err,written,string) //written--指定字符串要被写入的字节数
在 Linux 上,当以追加模式打开文件时,写入无法指定位置。 内核会忽略位置参数,并始终将数据追加到文件的末尾。
在 Windows 上,如果文件描述符连接到控制台(例如 fd == 1
或 stdout
),则无论使用何种编码,包含非 ASCII 字符的字符串默认情况下都不会被正确地渲染。 通过使用 chcp 65001
命令更改活动的代码页,可以将控制台配置为正确地渲染 UTF-8。 详见 chcp 文档。
2.44Fs.writeFile():将数据写入到指定的文件。(如果不指定位置会覆盖之前的数据从最开始的位置写入)
fs.writeFile(file, data[, options], callback);//异步 fs.writeFileSync(file, data[, options]);//同步 //当 file 是一个文件名时,异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。 data 可以是字符串或 buffer。 //当 file 是一个文件描述符时,行为类似于直接调用 fs.write()(建议使用)。 请参阅以下有关使用文件描述符的说明。 //如果 data 是一个 buffer,则 encoding 选项会被忽略。 //position<string>|<object>--如果该参数为字符串时指示为字符串编码 //--encoding:字符编码 //--mode--配置权限 //flag--配置文件标志
在同一个文件上多次使用 fs.writeFile()
且不等待回调是不安全的。 对于这种情况,建议使用 fs.createWriteStream()
。
没有file时会先创建再写入。
如果file时一个文件描述符(fd)时,按照以下语法写入:
fs.write(fd, Buffer.from(data, options.encoding), callback);
2.45Fs.writev():将一个ArrayBufferView数组写入指定的fd。
fs.writev(fd, buffers[, position], callback);//异步 fs.writevSync(fd, buffers[, position]);//同步--返回写入的字节数 //fd--文件描述符 //buffers--<ArrayBufferView[]> //position--指定文件开头的偏移量 //callback(err,bytesWritten,buffers) //bytesWritten--写入的字节数
三、fs的Promise API与FileHandle类
在了解这部分内容之前建议先了解Promise,我之前有一篇详细的Promise的解析博客可以提供参考:ES6入门八:Promise异步编程与模拟实现源码。
在官方文档中明确表示为一组备用的API,也就是这部分API在将来可能发生变化,慎用。(有空闲的时间再来补充)