文章目录
- 简言
- [File system](#File system)
-
- [Promise example 承诺示例](#Promise example 承诺示例)
- [Callback example 回调示例](#Callback example 回调示例)
- [Synchronous example 同步示例](#Synchronous example 同步示例)
- [Promises API 承诺API](#Promises API 承诺API)
-
- [Class: FileHandle](#Class: FileHandle)
-
- [Event: 'close' 关闭文件](#Event: 'close' 关闭文件)
- [filehandle.appendFile(data[, options]) 添加数据](#filehandle.appendFile(data[, options]) 添加数据)
- [filehandle.chmod(mode) 修改权限](#filehandle.chmod(mode) 修改权限)
- [filehandle.chown(uid, gid) 修改文件所有权](#filehandle.chown(uid, gid) 修改文件所有权)
- [filehandle.close() 关闭文件句柄](#filehandle.close() 关闭文件句柄)
- [filehandle.createReadStream([options]) 创建阅读流](#filehandle.createReadStream([options]) 创建阅读流)
- [filehandle.createWriteStream([options]) 创建写入流](#filehandle.createWriteStream([options]) 创建写入流)
- filehandle.datasync()
- filehandle.fd
- [filehandle.read(buffer, offset, length, position) 读取数据](#filehandle.read(buffer, offset, length, position) 读取数据)
- filehandle.read([options])
- [filehandle.read(buffer[, options])](#filehandle.read(buffer[, options]))
- [filehandle.readableWebStream([options]) 获取读取流](#filehandle.readableWebStream([options]) 获取读取流)
- [filehandle.readFile(options) 读取文件内容](#filehandle.readFile(options) 读取文件内容)
- [filehandle.readLines([options]) 按行读取](#filehandle.readLines([options]) 按行读取)
- [filehandle.readv(buffers[, position])](#filehandle.readv(buffers[, position]))
- filehandle.stat([options])
- [filehandle.sync() 数据刷新](#filehandle.sync() 数据刷新)
- [filehandle.truncate(len) 文件数据截取](#filehandle.truncate(len) 文件数据截取)
- [filehandle.utimes(atime, mtime)](#filehandle.utimes(atime, mtime))
- [filehandle.write(buffer, offset[, length[, position]]) buffer数据添加](#filehandle.write(buffer, offset[, length[, position]]) buffer数据添加)
- [filehandle.write(buffer[, options])](#filehandle.write(buffer[, options]))
- [filehandle.write(string[, position[, encoding]]) 字符串数据添加](#filehandle.write(string[, position[, encoding]]) 字符串数据添加)
- [filehandle.writeFile(data, options) 数据写入到文件](#filehandle.writeFile(data, options) 数据写入到文件)
- [filehandle.writev(buffers[, position]) buffer数据数组写入](#filehandle.writev(buffers[, position]) buffer数据数组写入)
- [fsPromises.access(path[, mode])](#fsPromises.access(path[, mode]))
- [fsPromises.appendFile(path, data[, options]) 向文件追加数据](#fsPromises.appendFile(path, data[, options]) 向文件追加数据)
- [fsPromises.chmod(path, mode) 更改文件权限](#fsPromises.chmod(path, mode) 更改文件权限)
- [fsPromises.chown(path, uid, gid)更改文件的所有权](#fsPromises.chown(path, uid, gid)更改文件的所有权)
- [fsPromises.copyFile(src, dest[, mode]) 复制文件](#fsPromises.copyFile(src, dest[, mode]) 复制文件)
- [fsPromises.lchmod(path, mode)](#fsPromises.lchmod(path, mode))
- [fsPromises.lchown(path, uid, gid)](#fsPromises.lchown(path, uid, gid))
- [fsPromises.lutimes(path, atime, mtime)](#fsPromises.lutimes(path, atime, mtime))
- [fsPromises.link(existingPath, newPath) 创建链接](#fsPromises.link(existingPath, newPath) 创建链接)
- [fsPromises.lstat(path[, options])](#fsPromises.lstat(path[, options]))
- [fsPromises.mkdir(path[, options]) 异步创建目录](#fsPromises.mkdir(path[, options]) 异步创建目录)
- [fsPromises.mkdtemp(prefix[, options]) 创建临时目录](#fsPromises.mkdtemp(prefix[, options]) 创建临时目录)
- [fsPromises.open(path, flags[, mode]) 打开文件](#fsPromises.open(path, flags[, mode]) 打开文件)
- [fsPromises.opendir(path[, options]) 打开文件目录](#fsPromises.opendir(path[, options]) 打开文件目录)
- [fsPromises.readdir(path[, options]) 读取目录内容](#fsPromises.readdir(path[, options]) 读取目录内容)
- [fsPromises.readFile(path[, options]) 读取文件](#fsPromises.readFile(path[, options]) 读取文件)
- [fsPromises.readlink(path[, options]) 读取链接内容](#fsPromises.readlink(path[, options]) 读取链接内容)
- [fsPromises.realpath(path[, options])](#fsPromises.realpath(path[, options]))
- [fsPromises.rename(oldPath, newPath) 移动](#fsPromises.rename(oldPath, newPath) 移动)
- [fsPromises.rmdir(path[, options]) 删除目录](#fsPromises.rmdir(path[, options]) 删除目录)
- [fsPromises.rm(path[, options]) 删除文件和目录](#fsPromises.rm(path[, options]) 删除文件和目录)
- [fsPromises.stat(path[, options]) 返回文件信息](#fsPromises.stat(path[, options]) 返回文件信息)
- [fsPromises.statfs(path[, options]) 返回已挂载文件系统的相关信息。](#fsPromises.statfs(path[, options]) 返回已挂载文件系统的相关信息。)
- [fsPromises.symlink(target, path[, type]) 创建符号链接](#fsPromises.symlink(target, path[, type]) 创建符号链接)
- [fsPromises.truncate(path[, len]) 截取内容](#fsPromises.truncate(path[, len]) 截取内容)
- [fsPromises.unlink(path) 删除链接或文件](#fsPromises.unlink(path) 删除链接或文件)
- [fsPromises.utimes(path, atime, mtime) 修改文件时间](#fsPromises.utimes(path, atime, mtime) 修改文件时间)
- [fsPromises.watch(filename[, options]) 监听文件](#fsPromises.watch(filename[, options]) 监听文件)
- [fsPromises.writeFile(file, data[, options]) 数据写入](#fsPromises.writeFile(file, data[, options]) 数据写入)
- fsPromises.constants
- 结语
简言
通过 node:fs 模块,可以以标准 POSIX 函数为模型与文件系统进行交互。
File system
通过 node:fs 模块,可以以标准 POSIX 函数为模型与文件系统进行交互。
要使用基于承诺的应用程序接口:
javascript
import * as fs from 'node:fs/promises';
使用回调和同步 API:
javascript
import * as fs from 'node:fs';
所有文件系统操作都有同步、回调和基于承诺的形式,并可使用 CommonJS 语法和 ES6 模块 (ESM) 访问。
Promise example 承诺示例
基于承诺的操作会返回一个承诺,该承诺会在异步操作完成时兑现。
javascript
import { unlink } from 'node:fs/promises';
try {
await unlink('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (error) {
console.error('there was an error:', error.message);
}
Callback example 回调示例
回调形式将完成回调函数作为最后一个参数,并异步调用操作。传递给完成回调函数的参数取决于方法,但第一个参数总是为异常保留。如果操作成功完成,则第一个参数为空或undefined(未定义)。
javascript
import { unlink } from 'node:fs';
unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
在需要最高性能(包括执行时间和内存分配)时,基于回调的 node:fs 模块 API 版本比使用 promise API 更为可取。
Synchronous example 同步示例
同步 API 会阻止 Node.js 事件循环和 JavaScript 的进一步执行,直到操作完成。异常会立即抛出,可以使用 try...catch 进行处理,也可以让异常冒泡。
javascript
import { unlinkSync } from 'node:fs';
try {
unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (err) {
// handle the error
}
Promises API 承诺API
fs/promises API 提供返回承诺的异步文件系统方法。
promise API 使用底层 Node.js 线程池在事件循环线程之外执行文件系统操作。这些操作不是同步或线程安全的。在对同一文件执行多个并发修改时必须小心谨慎,否则可能会导致数据损坏。
Class: FileHandle
<FileHandle> 对象是数字文件描述符的对象包装器。
<FileHandle> 对象的实例由 fsPromises.open() 方法创建。
所有 <FileHandle> 对象都是 <EventEmitter>s 。
如果未使用 filehandle.close() 方法关闭 <FileHandle> 文件,系统将尝试自动关闭文件描述符并发出进程警告,以帮助防止内存泄漏。请不要依赖这种行为,因为它可能不可靠,文件可能无法关闭。相反,请始终显式关闭 <FileHandle>s 文件。Node.js 今后可能会更改此行为。
Event: 'close' 关闭文件
当 <FileHandle> 已关闭且不能再使用时,"close "事件就会被触发。
filehandle.appendFile(data[, options]) 添加数据
参数:
- data ------ <string> | <Buffer> | <TypedArray> | <DataView> | <AsyncIterable> | <Iterable> | <Stream>
- options ------ 配置对象
- encoding ------ 默认值:'utf8'
- flush ------ 如果为 "true",底层文件描述符将在关闭前被刷新。默认值:false。
- 返回值 成功后返回undefined。
filehandle.writeFile() 的别名。
在对文件句柄进行操作时,模式不能从 fsPromises.open() 设置的模式进行更改。因此,这等同于 filehandle.writeFile()。
filehandle.chmod(mode) 修改权限
mode------ 文件模式位掩码。
修改文件的权限。
权限可以用以下几种方式来表示:
-
数值:如0o777 (所有用户都有读、写和执行权限)
-
字符串:如'777' (同上)
-
或者使用符号:如u+x (给文件所有者添加执行权限)
更多详细信息请参考linux的文件修改权限命令。
filehandle.chown(uid, gid) 修改文件所有权
- uid ------ 文件新所有者的用户 ID。
- gid ------ 文件新组的组 ID。
更改文件的所有权。
filehandle.close() 关闭文件句柄
在等待句柄上的任何待处理操作完成后,关闭文件句柄。
javascript
import { open } from "node:fs/promises";
let filehandle;
try {
filehandle = await open("thefile.txt", "r");
console.log(filehandle.readFile());
} catch (error) {
} finally {
if (filehandle) {
await filehandle.close();
}
}
filehandle.createReadStream([options]) 创建阅读流
参数:
- options ------ 配置对象
- encoding ------ 默认值:空。
- autoClose ------ 是否自动关闭 默认值:true。
- emitClose ------ 关闭后是否发出关闭事件 默认值:true。
- start ------ 开始索引
- end ------ 结束索引
- highWaterMark ------ 默认值:64 * 1024
与 <stream.Readable> 的 16 KiB 默认 highWaterMark 不同,此方法返回的流的默认 highWaterMark 为 64 KiB。
选项可以包含开始和结束值,以便从文件中读取一定范围的字节,而不是整个文件。start 和 end 都是包容性的,从 0 开始计数,允许的值范围是 [0,Number.MAX_SAFE_INTEGER]。如果省略 start 或未定义 start,filehandle.createReadStream() 将从当前文件位置开始顺序读取。编码可以是 接受的任何一种编码。
如果 FileHandle 指向只支持阻塞读取的字符设备(如键盘或声卡),则读取操作在数据可用前不会结束。这会导致进程无法退出,数据流无法自然关闭。
默认情况下,数据流销毁后会发出 "关闭 "事件。将 emitClose 选项设为 false 可以改变这种行为。
如果 autoClose 为 false,那么即使出现错误,文件描述符也不会被关闭。关闭文件描述符并确保没有文件描述符泄漏是应用程序的责任。如果将 autoClose 设为 true(默认行为),在出现 "错误 "或 "结束 "时,文件描述符将自动关闭。
示例:读取 100 字节文件的最后 10 字节:
javascript
import { open } from 'node:fs/promises';
const fd = await open('sample.txt');
fd.createReadStream({ start: 90, end: 99 });
filehandle.createWriteStream([options]) 创建写入流
参数:
- options ------ 配置对象
- encoding ------ 默认值:空。
- autoClose ------ 是否自动关闭 默认值:true。
- emitClose ------ 关闭后是否发出关闭事件 默认值:true。
- start ------ 开始索引
- highWaterMark ------ 默认值:64 * 1024
- flush ------ 如果为 "true",底层文件描述符将在关闭前被刷新。默认值:false。
选项还可以包括一个起始选项,允许在文件开始后的某个位置写入数据,允许的值范围是[0, Number.MAX_SAFE_INTEGER]。修改文件而不是替换文件,可能需要将 flags open 选项设置为 r+ 而不是默认的 r。
如果将 autoClose 设为 true(默认行为),那么在 "出错 "或 "完成 "时,文件描述符将自动关闭。如果 autoClose 为 false,那么即使出现错误,文件描述符也不会关闭。关闭文件描述符并确保没有文件描述符泄漏是应用程序的责任
默认情况下,数据流销毁后会发出 "关闭 "事件。将 emitClose 选项设为 false 可以改变这种行为。
filehandle.datasync()
强制与文件相关的所有当前排队 I/O 操作进入操作系统的同步 I/O 完成状态。
详情请参考 POSIX fdatasync(2) 文档。
与 filehandle.sync 不同,该方法不会刷新已修改的元数据。
filehandle.fd
由 <FileHandle> 对象管理的数字文件描述符。
filehandle.read(buffer, offset, length, position) 读取数据
参数:
- buffer <Buffer> | <TypedArray> | <DataView> 将读取的文件数据填入的缓冲区。
- offset <整数> 缓冲区中开始填充数据的位置。默认值:0
- length <整数> 要读取的字节数。默认值:buffer.byteLength - 偏移量
- position <integer> | <bigint> | <null> 从文件开始读取数据的位置。如果为空或-1,将从当前文件位置读取数据,并更新位置。如果 position 为非负整数,当前文件位置将保持不变。默认值::空
-返回值,使用具有两个属性的对象成功后执行:- bytesRead --- 读取的字节数
- buffer ------ 传递的缓冲区参数的引用。
从文件中读取数据并将其存储在给定的缓冲区中。
如果文件没有被同时修改,当读取的字节数为零时,文件结束。
javascript
import { open } from "node:fs/promises";
let filehandle;
try {
filehandle = await open("./src/file/thefile.txt", "r");
const { bytesRead, buffer } = await filehandle.read();
console.log(bytesRead, buffer.toString());
} catch (error) {
console.log(error);
} finally {
if (filehandle) {
await filehandle.close();
}
}
filehandle.read([options])
从文件中读取数据并将其存储在给定的缓冲区中。
如果文件没有被同时修改,当读取的字节数为零时,文件结束。
filehandle.read(buffer[, options])
从文件中读取数据并将其存储在给定的缓冲区中。
如果文件没有被同时修改,当读取的字节数为零时,文件结束。
filehandle.readableWebStream([options]) 获取读取流
返回可用于读取文件数据的 ReadableStream。
如果此方法被调用多次,或在 FileHandle 关闭或关闭后被调用,则会产生错误。
javascript
import {
open,
} from 'node:fs/promises';
const file = await open('./some/file/to/read');
for await (const chunk of file.readableWebStream())
console.log(chunk);
await file.close();
虽然 ReadableStream 会读完文件,但不会自动关闭 FileHandle。用户代码仍必须调用 fileHandle.close() 方法。
filehandle.readFile(options) 读取文件内容
异步读取文件的全部内容。
如果选项是字符串,则指定编码。
<FileHandle> 必须支持读取。
如果在文件句柄上调用了一个或多个 filehandle.read(),然后又调用了 filehandle.readFile(),那么数据将从当前位置读取,直到文件结束。它并不总是从文件开头读取数据。
javascript
try {
filehandle = await open("./src/file/thefile.txt", "r");
const buff = await filehandle.readFile();
console.log(buff.toString());
filehandle.close();
filehandle = await open("./src/file/thefile.txt", "r");
let res = await filehandle.readFile({ encoding: "utf8" });
console.log(res.toString());
} catch (error) {
console.log(error);
} finally {
if (filehandle) {
await filehandle.close();
}
}
filehandle.readLines([options]) 按行读取
参数:
- oprions<对象
- encoding <string> 默认值:null
- autoClose <boolean> 默认值:true
- emitClose <布尔> 默认值: true
- start <整数
- end <整数> 默认值:Infinity
- highWaterMark <整数> 默认值:64 * 1024
在文件上创建读取线接口和流的方便方法。有关选项,请参阅 filehandle.createReadStream() 。
javascript
import { open } from 'node:fs/promises';
const file = await open('./some/file/to/read');
for await (const line of file.readLines()) {
console.log(line);
}
filehandle.readv(buffers[, position])
参数:
- buffers ------ buffer 数组
- position ------ 从文件开头读取数据的偏移量。如果 position 不是数字,数据将从当前位置读取。默认值:空
- 返回值 ------ 成功后执行一个包含两个属性的对象:
- bytesRead ------ 读取的字节数。
- buffers ------ 属性,该属性包含对缓冲区输入的引用。
从文件读取并写入 <ArrayBufferView> 数组
filehandle.stat([options])
选项 <对象
bigint <boolean>返回的 <fs.Stats> 对象中的数值是否应为 bigint。默认值:false。
返回值:<Promise> 使用文件的 <fs.Stats> 实现。
filehandle.sync() 数据刷新
请求将打开的文件描述符的所有数据刷新到存储设备。具体实现取决于操作系统和设备。详情请参考 POSIX fsync(2) 文档。
filehandle.truncate(len) 文件数据截取
截断文件。
如果文件大于 len 字节,文件中将只保留前 len 字节。
下面的示例只保留了文件的前四个字节:
javascript
import { open } from 'node:fs/promises';
let filehandle = null;
try {
filehandle = await open('temp.txt', 'r+');
await filehandle.truncate(4);
} finally {
await filehandle?.close();
}
如果文件先前短于 len 字节,则文件将被扩展,扩展部分将填充空字节('\0'):
如果 len 为负数,则使用 0。
filehandle.utimes(atime, mtime)
更改 <FileHandle> 引用对象的文件系统时间戳,然后在成功后履行承诺,不含任何参数。
filehandle.write(buffer, offset[, length[, position]]) buffer数据添加
参数:
- 缓冲区 <Buffer> | <TypedArray> | <DataView>
- offset <整数> 要写入的数据在缓冲区中的起始位置。
- length <整数> 缓冲区中要写入的字节数。默认值:buffer.byteLength - 偏移量
- position <integer> | <null> 从文件开头写入缓冲区数据的偏移量。如果 position 不是数字,数据将写入当前位置。更多详情,请参阅 POSIX pwrite(2) 文档。默认值:空
- 返回值<承诺
将缓冲区写入文件。
承诺通过一个包含两个属性的对象来实现:
bytesWritten <整数> 写入的字节数。
buffer <Buffer> | <TypedArray> | <DataView> 对写入的缓冲区的引用。
在同一文件上多次使用 filehandle.write() 而不等待承诺实现(或拒绝)是不安全的。在这种情况下,请使用 filehandle.createWriteStream()。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。内核会忽略位置参数,并始终将数据追加到文件末尾。
filehandle.write(buffer[, options])
将缓冲区写入文件。
与上面的 filehandle.write 函数类似,该版本需要一个可选的选项对象。如果没有指定选项对象,则默认使用上述值。
filehandle.write(string[, position[, encoding]]) 字符串数据添加
将字符串写入文件。如果字符串不是字符串,承诺将被拒绝,并显示错误。
承诺通过一个包含两个属性的对象来实现:
- bytesWritten <整数> 写入的字节数
- buffer <string> 写入字符串的引用。
在同一文件上多次使用 filehandle.write() 而不等待承诺实现(或拒绝)是不安全的。在这种情况下,请使用 filehandle.createWriteStream()。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。内核会忽略位置参数,并始终将数据追加到文件末尾。
filehandle.writeFile(data, options) 数据写入到文件
数据可以是字符串、缓冲区、 或 对象。成功后,将履行承诺,不带参数。
如果选项是字符串,则指定编码。
<FileHandle> 必须支持写入。
在同一文件上多次使用 filehandle.writeFile() 而不等待承诺实现(或拒绝)是不安全的。
如果在一个文件句柄上调用了一次或多次 filehandle.write(),然后又调用了一次 filehandle.writeFile(),数据将从当前位置写入,直到文件结束。它并不总是从文件开头写起。
javascript
try {
filehandle = await open("./src/file/thefile.txt", "r");
const buff = await filehandle.readFile();
console.log(buff.toString());
filehandle.close();
filehandle = await open("./src/file/thefile.txt", "r+");
await filehandle.truncate(0);
filehandle.write("你好");
filehandle.writeFile("\nHHH");
filehandle.sync();
} catch (error) {
console.log(error);
} finally {
if (filehandle) {
await filehandle.close();
}
}
filehandle.writev(buffers[, position]) buffer数据数组写入
将 <ArrayBufferView>s 数组写入文件。
在同一文件上多次调用 writev() 而不等待承诺实现(或拒绝)是不安全的。
在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略位置参数,并始终将数据追加到文件末尾。
fsPromises.access(path[, mode])
测试用户对 path 指定的文件或目录的权限。模式参数是一个可选整数,用于指定要执行的可访问性检查。模式应为 fs.constants.F_OK,或由 fs.constants.R_OK、fs.constants.W_OK 和 fs.constants.X_OK 中任意一个的 bitwise OR 组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK)。请查看文件访问常量,了解模式的可能值。
如果无障碍检查成功,则履行承诺,但不产生任何值。如果任何可访问性检查失败,则会以 <Error> 对象拒绝该承诺。下面的示例检查当前进程是否可以读写 /etc/passwd 文件。
javascript
import { access, constants } from 'node:fs/promises';
try {
await access('/etc/passwd', constants.R_OK | constants.W_OK);
console.log('can access');
} catch {
console.error('cannot access');
}
不建议在调用 fsPromises.open() 之前使用 fsPromises.access() 检查文件的可访问性。这样做会引入竞赛条件,因为其他进程可能会在两次调用之间改变文件的状态。相反,用户代码应直接打开/读取/写入文件,并处理文件不可访问时出现的错误。
fsPromises.appendFile(path, data[, options]) 向文件追加数据
参数:
- path ------ 文件路径
- data ------ 数据
- options ------ 配置对象
- encoding ------ 编码,默认值:'utf8'
- mode ------ 文件权限,默认0o666
- flag ------ 操作类型标志。默认'a',即打开文件进行添加。如果文件不存在,则将创建该文件。
- flush ------ 如果为 "true",底层文件描述符将在关闭前被刷新。默认值:false。
异步向文件追加数据,如果文件不存在,则创建文件。
如果选项是字符串,则指定编码。
模式(mode)选项只影响新创建的文件。详情请参阅 fs.open()。
路径可指定为已打开用于添加的 <FileHandle> 文件(使用 fsPromises.open())。
typescript
import { appendFile } from "node:fs/promises";
appendFile("./src/file/thefile.txt", "\n我是appendFile添加的。");
fsPromises.chmod(path, mode) 更改文件权限
更改文件权限。
fsPromises.chown(path, uid, gid)更改文件的所有权
更改文件的所有权。
fsPromises.copyFile(src, dest[, mode]) 复制文件
参数:
- src ------ 要复制的源文件名。
- dest ------ 复制操作的目标文件名。
- mode ------ 指定复制操作行为的可选修饰符。可以创建一个由两个或两个以上值的 bitwise OR 组成的掩码(例如,fs.constants.COPYFILE_EXCL |fs.constants.COPYFILE_FICLONE) 默认值:0。
- fs.constants.COPYFILE_EXCL:如果 dest 已经存在,复制操作将失败。
- fs.constants.COPYFILE_FICLONE:复制操作将尝试创建写入时复制重链接。如果平台不支持写入时复制,则会使用后备复制机制。
- fs.constants.COPYFILE_FICLONE_FORCE:复制操作将尝试创建写时复制重链接。如果平台不支持写入时复制,则操作将失败。
异步复制 src 到 dest。默认情况下,如果 dest 已存在,则会被覆盖。
不保证复制操作的原子性。如果在目标文件打开供写入后发生错误,系统将尝试删除目标文件。
typescript
import { copyFile, constants } from 'node:fs/promises';
try {
await copyFile('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');
} catch {
console.error('The file could not be copied');
}
// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
// 使用 COPYFILE_EXCL,如果 destination.txt 存在,操作将失败。
try {
await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
console.log('source.txt was copied to destination.txt');
} catch {
console.error('The file could not be copied');
}
fsPromises.lchmod(path, mode)
更改符号链接的权限。
此方法仅在 macOS 上实现。
fsPromises.lchown(path, uid, gid)
更改符号链接的所有权。
fsPromises.lutimes(path, atime, mtime)
更改文件的访问和修改时间的方法与 fsPromises.utimes() 相同,不同之处在于,如果路径指向符号链接,则不会取消引用链接:而是更改符号链接本身的时间戳。
fsPromises.link(existingPath, newPath) 创建链接
创建从 existingPath 到 newPath 的新链接。详情请查看 POSIX link(2) 文档。
fsPromises.lstat(path[, options])
等同于 fsPromises.stat(),除非 path 指向符号链接,在这种情况下,链接本身会被统计,而不是它指向的文件。详情请参考 POSIX lstat(2) 文档。
fsPromises.mkdir(path[, options]) 异步创建目录
异步创建目录。
参数:
- path ------ 路径
- options ------ 配置选项。
- recursive ------ 是否递归 默认值:false
- mode ------ 文件权限,Windows 不支持。默认值:0o777。
- 返回值------成功后,如果递归为假,则执行未定义;如果递归为真,则执行创建的第一个目录路径。
可选的选项参数可以是一个指定模式(权限和粘性位)的整数,也可以是一个带有模式属性和递归属性的对象,后者表示是否应创建父目录。当 path 是一个已存在的目录时,调用 fsPromises.mkdir() 只会在递归属性为 false 时导致拒绝。
typescript
import { mkdir } from 'node:fs/promises';
try {
const projectFolder = new URL('./test/project/', import.meta.url);
const createDir = await mkdir(projectFolder, { recursive: true });
console.log(`created ${createDir}`);
} catch (err) {
console.error(err.message);
}
fsPromises.mkdtemp(prefix[, options]) 创建临时目录
创建一个唯一的临时目录。在所提供前缀的末尾添加六个随机字符,即可生成唯一的目录名。由于平台不一致,请避免在前缀中使用尾随 X 字符。某些平台,尤其是 BSD,可以返回超过六个随机字符,并用随机字符替换前缀中的尾随 X 字符。
参数:
- prefix ------ 前缀
- options ------ 配置对象
- encoding ------ 编码, 默认utf8
- 返回值------使用包含新创建临时目录的文件系统路径的字符串执行。
可选的选项参数可以是一个指定编码的字符串,也可以是一个带有编码属性的对象,该属性指定了要使用的字符编码。
typescript
import { mkdtemp } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
try {
let str = await mkdtemp(join(tmpdir(), "foo-"));
console.log("临时目录", str);
} catch (err) {
console.error(err);
}
fsPromises.mkdtemp() 方法会将随机选择的六个字符直接追加到前缀字符串中。例如,给定目录 /tmp,如果要在 /tmp 中创建临时目录,前缀必须以特定平台的尾部路径分隔符(require('node:path').sep)结尾。
fsPromises.open(path, flags[, mode]) 打开文件
打开 <FileHandle> 文件。
参数:
- path ------ 文件路径。
- flags ------ 文件操作系统类型标志,默认'r',即可读。
- mode ------ 如果创建文件,则设置文件模式(权限和粘性位)。默认值:0o666(可读可写)
-返回:<Promise> 使用 <FileHandle> 对象执行。
详情请参考 POSIX open(2) 文档。
某些字符(< > : " / \ | ? *)在 Windows 下是保留字符,如文件命名、路径和命名空间中所述。在 NTFS 下,如果文件名包含冒号,Node.js 将打开文件系统流,如 MSDN 页面所述。
fsPromises.opendir(path[, options]) 打开文件目录
参数:
- path <string> | <Buffer> | <URL> ------ 路径
- options <对象
- 编码 <string> | <null> 默认:"utf8
- bufferSize <number> 从目录读取时内部缓冲的目录条目的数量。数值越大,性能越好,但内存占用也越高。默认值:32
- recursive <boolean>解析后的目录将是一个包含所有子文件和目录的 。默认值:false
- 返回:<Promise> 以 <fs.Dir> 实现。
异步打开一个目录进行迭代扫描。更多详情,请参阅 POSIX opendir(3) 文档。
创建 <fs.Dir>,其中包含读取和清理目录的所有函数。
编码选项用于设置打开目录和后续读取操作时的路径编码。
使用异步迭代的示例:
typescript
import { opendir } from "node:fs/promises";
try {
const dir = await opendir("./");
for await (const dirent of dir) {
console.log("drent::", dirent.name);
}
} catch (err) {
console.error(err);
}
使用异步迭代器时,<fs.Dir> 对象将在迭代器退出后自动关闭。
fsPromises.readdir(path[, options]) 读取目录内容
参数:
- path ------ 目录路径
- oprions ------ 配置对象。
- encoding ------ 默认'utf8'
- withFileTypes ------ 默认false
- recursive ------ 为 true 时,将递归读取目录内容。在递归模式下,它会列出所有文件、子文件和目录。默认值:false。
- 返回值 ------ 使用目录中不包含". "和"... "的文件名数组来执行。
读取目录内容。
可选的选项参数可以是一个指定编码的字符串,也可以是一个带有编码属性的对象,该属性指定了文件名使用的字符编码。如果编码设置为 "缓冲区",返回的文件名将作为 <Buffer> 对象传递。
如果 options.withFileTypes 设置为 true,返回的数组将包含 <fs.Dirent> 对象。
typescript
try {
const files = await readdir("./");
for (const file of files) {
console.log("file::", file);
}
} catch (err) {
console.error(err);
}
fsPromises.readFile(path[, options]) 读取文件
参数:
- path ------ <string> | <Buffer> | <URL> | <FileHandle> 文件名或文件句柄FileHandle。
- options ------ 配置对象。
- encoding ------ 编码,默认null。
- flag ------ 文件系统操作标志。默认'r',可读。
- signal ------ 允许终止正在读取的文件
- 返回:<Promise> 使用文件内容执行。
异步读取文件的全部内容。
如果没有指定编码(使用 options.encoding),数据将以 <Buffer> 对象的形式返回。否则,数据将是一个字符串。
如果 options 是字符串,则指定编码。
当路径为目录时,fsPromises.readFile() 的行为与特定平台有关。在 macOS、Linux 和 Windows 平台上,承诺将被拒绝并显示错误。在 FreeBSD 上,将返回目录内容的表示形式。
读取运行代码同一目录下 package.json 文件的示例:
typescript
import { readFile } from "node:fs/promises";
try {
const contents = await readFile("./package.json", { encoding: "utf8" });
console.log(contents);
} catch (err) {
console.error(err.message);
}
可以使用 <AbortSignal> 终止正在进行的 readFile。如果请求被中止,返回的承诺将被拒绝,并显示 AbortError:
typescript
import { readFile } from 'node:fs/promises';
try {
const controller = new AbortController();
const { signal } = controller;
const promise = readFile(fileName, { signal });
// Abort the request before the promise settles.
controller.abort();
await promise;
} catch (err) {
// When a request is aborted - err is an AbortError
console.error(err);
}
中止正在进行的请求不会中止单个操作系统请求,而是中止 fs.readFile 执行的内部缓冲。
任何指定的 <FileHandle> 必须支持读取。
fsPromises.readlink(path[, options]) 读取链接内容
参数:
- path路径 <string> | <Buffer> | <URL>
- options选项 <string> | <Object
- encoding 编码 <string> 默认:"utf8
- 返回值:<Promise>(承诺) 成功时使用 linkString 履行。
读取 path 指向的符号链接的内容。详情请参见 POSIX readlink(2) 文档。成功后,将使用 linkString 履行承诺。
可选的选项参数可以是一个指定编码的字符串,也可以是一个带有编码属性的对象,该属性指定了返回的链接路径要使用的字符编码。如果编码设置为 "缓冲区",返回的链接路径将作为 <Buffer> 对象传递。
fsPromises.realpath(path[, options])
使用与 fs.realpath.native() 函数相同的语义确定路径的实际位置。
只支持可转换为 UTF8 字符串的路径。
可选的选项参数可以是一个指定编码的字符串,也可以是一个带有编码属性的对象,该属性指定了路径使用的字符编码。如果编码设置为 "缓冲区",返回的路径将以 <Buffer> 对象的形式传递。
在 Linux 上,当 Node.js 与 musl libc 链接时,procfs 文件系统必须挂载在 /proc 上,此函数才能工作。Glibc 没有此限制。
fsPromises.rename(oldPath, newPath) 移动
将 oldPath 重命名为 newPath。
fsPromises.rmdir(path[, options]) 删除目录
参数:
- path ------ 路径。
- options ------ 配置对象.
- maxRetries ------ 如果遇到 EBUSY、EMFILE、ENFILE、ENOTEMPTY 或 EPERM 错误,Node.js 会重试操作,每次重试的线性延迟时间为 retryDelay 毫秒。该选项表示重试次数。如果递归选项不为真,该选项将被忽略。默认值:0。
- recursive ------ 递归,如果为 true,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值:false。已废弃。
- retryDelay ------ 两次重试之间的等待时间(毫秒)。如果递归选项不为真,该选项将被忽略。默认值:100。
删除 path 所标识的目录。
在文件(而非目录)上使用 fsPromises.rmdir(),在 Windows 下会出现 ENOENT 错误,在 POSIX 下会出现 ENOTDIR 错误,导致承诺被拒绝。
要获得与 rm -rf Unix 命令类似的行为,可使用 fsPromises.rm(),并在其中加入选项 { recursive: true, force: true }。
fsPromises.rm(path[, options]) 删除文件和目录
参数:
- path ------ 路径。
- options ------ 配置对象.
- maxRetries ------ 如果遇到 EBUSY、EMFILE、ENFILE、ENOTEMPTY 或 EPERM 错误,Node.js 会重试操作,每次重试的线性延迟时间为 retryDelay 毫秒。该选项表示重试次数。如果递归选项不为真,该选项将被忽略。默认值:0。
- recursive ------ 递归,如果为 true,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值:false。已废弃。
- retryDelay ------ 两次重试之间的等待时间(毫秒)。如果递归选项不为真,该选项将被忽略。默认值:100。
删除文件和目录(仿效标准 POSIX rm 工具)。
fsPromises.stat(path[, options]) 返回文件信息
返回给定路径的 <fs.Stats> 对象。
fsPromises.statfs(path[, options]) 返回已挂载文件系统的相关信息。
返回给定路径的 <fs.StatFs> 对象。
fsPromises.symlink(target, path[, type]) 创建符号链接
创建符号链接。
类型参数仅用于 Windows 平台,可以是 "dir"、"file "或 "junction "之一。如果类型参数不是字符串,Node.js 将自动检测目标类型并使用 "file "或 "dir"。如果目标不存在,将使用 "file"。Windows 连接点要求目标路径是绝对路径。使用 "junction "时,目标参数将自动规范化为绝对路径。NTFS 卷上的交界点只能指向目录。
fsPromises.truncate(path[, len]) 截取内容
将路径处的内容截断(缩短或延长长度)为 len 字节。
fsPromises.unlink(path) 删除链接或文件
如果 path 指向一个符号链接,则会删除该链接,而不会影响该链接指向的文件或目录。如果 path 指向的文件路径不是符号链接,则该文件将被删除。详情请参见 POSIX unlink(2) 文档。
fsPromises.utimes(path, atime, mtime) 修改文件时间
更改 path 引用对象的文件系统时间戳。
atime 和 mtime 参数遵循这些规则:
- 值可以是代表 Unix 纪元时间的数字、日期或数字字符串,如 "123456789.0"。
- 如果数值无法转换为数字,或者是 NaN、Infinity 或 -Infinity,则会出错。
fsPromises.watch(filename[, options]) 监听文件
参数:
- filename ------ 文件名或目录
- options------ 配置对象。
- persistent ------ 指示进程是否应在文件被监视期间继续运行。默认值:true。
- recursive ------ 指示是监视所有子目录,还是只监视当前目录。这适用于指定目录的情况,且仅适用于支持的平台(请参阅注意事项)。默认值:false。
- encoding ------ 指定传递给监听器的文件名所使用的字符编码。默认值:"utf8"。
- signal ------ 一个 <AbortSignal> 用于在观察者应该停止时发出信号。
- 返回值 ------ 带有属性的对象的 <AsyncIterator> :
- eventType ------ 变化的类型。
- filename ------ 已更改的文件名。
返回一个异步迭代器,用于监视文件名的变化,其中文件名可以是文件,也可以是目录。
typescript
const { watch } = require('node:fs/promises');
const ac = new AbortController();
const { signal } = ac;
setTimeout(() => ac.abort(), 10000);
(async () => {
try {
const watcher = watch(__filename, { signal });
for await (const event of watcher)
console.log(event);
} catch (err) {
if (err.name === 'AbortError')
return;
throw err;
}
})();
在大多数平台上,每当目录中出现或消失文件名时,都会发出 "rename"。
fs.watch() 的所有注意事项也适用于 fsPromises.watch()。
fsPromises.writeFile(file, data[, options]) 数据写入
参数:
- file <string> | <Buffer> | <URL> | <FileHandle> 文件名或 FileHandle
- data <string> | <Buffer> | <TypedArray> | <DataView> | <AsyncIterable> | <Iterable> | <Stream>
- 选项 <对象> | <字符串
- encoding 编码 <string> | 默认:'utf8
- mode 模式 <整数> 默认: 0o666
- flag <string> 查看文件系统标志支持。默认: 'w'。
- flush <boolean>如果所有数据已成功写入文件,且 flush 为 true,则使用 filehandle.sync() 清除数据。默认值:false。
- signal <AbortSignal> 允许终止正在进行的写文件操作。
- 返回:<Promise>成功时以未定义的方式实现。
数据可以是字符串、缓冲区、<AsyncIterable> 或 <Iterable> 对象。
如果数据是缓冲区,编码选项将被忽略。
如果选项是字符串,则指定编码。
模式选项只影响新创建的文件。详情请参阅 fs.open()。
任何指定的 <FileHandle> 必须支持写入。
在同一文件上多次使用 fsPromises.writeFile() 而不等待承诺结算是不安全的。
与 fsPromises.readFile 类似,fsPromises.writeFile 也是一种便捷方法,可在内部执行多次写调用,以写入传递给它的缓冲区。对于性能敏感的代码,可考虑使用 fs.createWriteStream() 或 filehandle.createWriteStream()。
可以使用 <AbortSignal> 取消 fsPromises.writeFile()。取消是 "尽力而为",可能仍有一定量的数据要写入。
typescript
import { writeFile } from 'node:fs/promises';
import { Buffer } from 'node:buffer';
try {
const controller = new AbortController();
const { signal } = controller;
const data = new Uint8Array(Buffer.from('Hello Node.js'));
const promise = writeFile('message.txt', data, { signal });
// Abort the request before the promise settles.
controller.abort();
await promise;
} catch (err) {
// When a request is aborted - err is an AbortError
console.error(err);
}
中止正在进行的请求不会中止单个操作系统请求,而是中止 fs.writeFile 执行的内部缓冲。
fsPromises.constants
返回一个包含文件系统操作常用常量的对象。该对象与 fs.constants 相同。更多详情,请参阅 FS 常量。
结语
结束了。