【Node】node的fs模块介绍及使用(一)

文章目录

  • 简言
  • [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 常量。

结语

结束了。

相关推荐
理想不理想v5 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
暮毅9 小时前
10.Node.js连接MongoDb
数据库·mongodb·node.js
~甲壳虫15 小时前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
~甲壳虫15 小时前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫15 小时前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
熊的猫16 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
前端青山1 天前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
GDAL1 天前
npm入门教程1:npm简介
前端·npm·node.js
郑小憨1 天前
Node.js简介以及安装部署 (基础介绍 一)
java·javascript·node.js
lin-lins2 天前
模块化开发 & webpack
前端·webpack·node.js