nodejs入门API之fs模块

时间:2024-01-18 23:29:50
  • 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,相反这些操作建议直接进行,不必要在操作之前进行检查,以免引发竞态。

 const file = 'package.json';

 // 检查当前目录中是否存在该文件。
fs.access(file, fs.constants.F_OK, (err) => {
console.log(`${file} ${err ? '不存在' : '存在'}`);
}); // 检查文件是否可读。
fs.access(file, fs.constants.R_OK, (err) => {
console.log(`${file} ${err ? '不可读' : '可读'}`);
}); // 检查文件是否可写。
fs.access(file, fs.constants.W_OK, (err) => {
console.log(`${file} ${err ? '不可写' : '可写'}`);
}); // 检查当前目录中是否存在该文件,以及该文件是否可写。
fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
if (err) {
console.error(
`${file} ${err.code === 'ENOENT' ? '不存在' : '只可读'}`);
} else {
console.log(`${file} 存在,且它是可写的`);
}
}); //同步检查
try {
fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);
console.log('可以读写');
} catch (err) {
console.error('无权访问');
}

来源于官方文档的示例

2.2 FS.appendFile():将数据追加到文件,如果文件不存在则创建文件。

fs.appendFile(path, data[, options], callback);//异步:options可以配置文件encoding、mode、flag【字符编码、权限值、文件可操作标志符】,如果写入一个字符串值只表示字符编码。
//callbakc:当操作不可操作时会传入error对象
fs.appendFileSync(path,data[,options]);//同步

path可以指定为已打开的文件的数字型文件描述符,用于追加文件数据。

 //为指定路径的文件追加数据
fs.appendFile('message.txt', '追加的数据', (err) => {
if (err) throw err;
console.log('数据已追加到文件');
});
//paht为已打开的文件数字型文件描述符(fd)
fs.open('message.txt', 'a', (err, fd) => {
if (err) throw err;
fs.appendFile(fd, '追加的数据', 'utf8', (err) => {
fs.close(fd, (err) => {
if (err) throw err;
});
if (err) throw err;
});
}); //同步示例一
try {
fs.appendFileSync('message.txt', '追加的数据');
console.log('数据已追加到文件');
} catch (err) {
/* 处理错误 */
}
//同步示例二
let fd;
try {
fd = fs.openSync('message.txt', 'a');
fs.appendFileSync(fd, '追加的数据', 'utf8');
} catch (err) {
/* 处理错误 */
} finally {
if (fd !== undefined)
fs.closeSync(fd);
}

来自官方文档的示例

2.3 Fs.chmod():修改文件权限。

fs.chmod(path,mode,callback);//异步:回调函数除了可能的异常对象,没有其他参数。
fs.chmodSync(path,mode);//同步

关于权限设置的mode参数值详细可参考第一节中的1.8和1.9的内容。

 fs.chmod('my_file.txt', 0o775, (err) => {
if (err) throw err;
console.log('文件 “my_file.txt” 的权限已被更改');
});

来自官方文档的示例

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])
 //示例一
const fs = require('fs'); // 默认情况下将创建或覆盖目标文件。
fs.copyFile('源文件.txt', '目标文件.txt', (err) => {
if (err) throw err;
console.log('源文件已拷贝到目标文件');
});
//示例二
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants; // 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
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 个字节会保留在文件中。

 //示例一
console.log(fs.readFileSync('temp.txt', 'utf8'));
// 打印: Node.js // 获取要截断的文件的文件描述符。
const fd = fs.openSync('temp.txt', 'r+'); // 将文件截断为前 4 个字节。
fs.ftruncate(fd, 4, (err) => {
assert.ifError(err);
console.log(fs.readFileSync('temp.txt', 'utf8'));
});
// 打印: Node //示例二
console.log(fs.readFileSync('temp.txt', 'utf8'));
// 打印: Node.js // 获取要截断的文件的文件描述符。
const fd = fs.openSync('temp.txt', 'r+'); // 将文件截断为前 10 个字节,但实际大小为 7 个字节。
fs.ftruncate(fd, 10, (err) => {
assert.ifError(err);
console.log(fs.readFileSync('temp.txt'));
});
// 打印: <Buffer 4e 6f 64 65 2e 6a 73 00 00 00>
// (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上无效)

 // 创建 /tmp/a/apple 目录,无论是否存在 /tmp 和 /tmp/a 目录。
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
});

来源官方文档的示例

2.24Fs.mkdtemp():创建唯一的临时目录。

fs.mkdtemp(prefix[, options], callback);//异步
fs.mkdtempSync(prefix[, options]);//同步

prefix(文件夹名称不要以x结尾);options<string | object>为一个字符串时直接表示字符编码,为对象时也只有一个encoding(字符编码)字段。

 //示例一
fs.mkdtemp(path.join(os.tmpdir(), '目录-'), (err, folder) => {
if (err) throw err;
console.log(folder);
// 打印: /tmp/目录-itXde2 或 C:\Users\...\AppData\Local\Temp\目录-itXde2
}); //示例二
// 新的临时目录的父目录。
const tmpDir = os.tmpdir(); // 此用法是错误的:
fs.mkdtemp(tmpDir, (err, folder) => {
if (err) throw err;
console.log(folder);
// 输出类似 `/tmpabc123`。
// 新的临时目录会被创建在文件系统根目录,而不是在 /tmp 目录中。
}); // 此用法是正确的:
const { sep } = require('path');
fs.mkdtemp(`${tmpDir}${sep}`, (err, folder) => {
if (err) throw err;
console.log(folder);
// 输出类似 `/tmp/abc123`。
// 新的临时目录会被创建在 /tmp 目录中。
});

来自官方文档的示例

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 字符串的路径。

 function rePath(pathName) {
fs.realpath("./fs/"+pathName + ".txt", 'utf8', function(err,resolvedPath){
if(err) throw err;
console.log(resolvedPath);
});
}

一个最简单的示例

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 已存在,则覆盖它。
 function rename(pathName){
fs.rename("./fs/"+pathName + ".txt","rename.txt",function (err) {
if(err) throw err;
console.log("重命名完成");
})
}

一个简单的示例

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在将来可能发生变化,慎用。(有空闲的时间再来补充)