Skip to content

文件系统

[稳定: 2 - 稳定]

稳定: 2 稳定性: 2 - 稳定

源代码: lib/fs.js

node:fs 模块允许以标准 POSIX 函数为模型的方式与文件系统交互。

要使用基于 Promise 的 API:

js
import * as fs from 'node:fs/promises'
js
const fs = require('node:fs/promises')

要使用回调和同步 API:

js
import * as fs from 'node:fs'
js
const fs = require('node:fs')

所有文件系统操作都具有同步、回调和基于 Promise 的形式,并且可以使用 CommonJS 语法和 ES6 模块 (ESM) 进行访问。

Promise 示例

基于 Promise 的操作返回一个 Promise,当异步操作完成时,该 Promise 将被 fulfilled。

js
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)
}
js
const { unlink } = require('node:fs/promises')

;(async function (path) {
  try {
    await unlink(path)
    console.log(`successfully deleted ${path}`)
  } catch (error) {
    console.error('there was an error:', error.message)
  }
})('/tmp/hello')

回调函数示例

回调函数形式将完成回调函数作为其最后一个参数,并异步调用操作。传递给完成回调函数的参数取决于方法,但第一个参数始终保留给异常。如果操作成功完成,则第一个参数为nullundefined

js
import { unlink } from 'node:fs'

unlink('/tmp/hello', err => {
  if (err) throw err
  console.log('successfully deleted /tmp/hello')
})
js
const { unlink } = require('node:fs')

unlink('/tmp/hello', err => {
  if (err) throw err
  console.log('successfully deleted /tmp/hello')
})

当需要最大性能(在执行时间和内存分配方面)时,node:fs 模块 API 的基于回调函数的版本优于使用 Promise API。

同步示例

同步 API 会阻塞 Node.js 事件循环和进一步的 JavaScript 执行,直到操作完成。异常会立即抛出,可以使用 try…catch 处理,或者可以允许其冒泡。

js
import { unlinkSync } from 'node:fs'

try {
  unlinkSync('/tmp/hello')
  console.log('successfully deleted /tmp/hello')
} catch (err) {
  // handle the error
}
js
const { unlinkSync } = require('node:fs')

try {
  unlinkSync('/tmp/hello')
  console.log('successfully deleted /tmp/hello')
} catch (err) {
  // handle the error
}

Promise API

[历史]

版本变更
v14.0.0作为 require('fs/promises') 暴露。
v11.14.0, v10.17.0此 API 不再是实验性的。
v10.1.0此 API 只能通过 require('fs').promises 访问。
v10.0.0添加于:v10.0.0

fs/promises API 提供了返回 Promise 的异步文件系统方法。

Promise API 使用底层的 Node.js 线程池在事件循环线程之外执行文件系统操作。这些操作不是同步的或线程安全的。在对同一文件执行多个并发修改时必须小心,否则可能会发生数据损坏。

类:FileHandle

添加于:v10.0.0

<FileHandle> 对象是数值文件描述符的对象包装器。

<FileHandle> 对象的实例由 fsPromises.open() 方法创建。

所有 <FileHandle> 对象都是 <EventEmitter>

如果 <FileHandle> 没有使用 filehandle.close() 方法关闭,它将尝试自动关闭文件描述符并发出进程警告,以帮助防止内存泄漏。请不要依赖此行为,因为它可能不可靠,并且文件可能不会关闭。相反,始终显式关闭 <FileHandle> 。Node.js 可能会在将来更改此行为。

事件: 'close'

新增于: v15.4.0

<FileHandle> 已关闭且无法再使用时,将发出 'close' 事件。

filehandle.appendFile(data[, options])

[历史记录]

版本变更
v21.1.0, v20.10.0现在支持 flush 选项。
v15.14.0, v14.18.0data 参数现在支持 AsyncIterableIterableStream
v14.0.0data 参数不再强制将不支持的输入转换为字符串。
v10.0.0新增于: v10.0.0

filehandle.writeFile() 的别名。

在操作文件句柄时,模式不能从使用 fsPromises.open() 设置的模式更改。因此,这等效于 filehandle.writeFile()

filehandle.chmod(mode)

新增于:v10.0.0

  • mode <整数> 文件模式位掩码。
  • 返回值:<Promise> 成功时返回 undefined

修改文件权限。参见 chmod(2)

filehandle.chown(uid, gid)

新增于:v10.0.0

  • uid <整数> 文件新的所有者用户 ID。
  • gid <整数> 文件新的所属组组 ID。
  • 返回值:<Promise> 成功时返回 undefined

更改文件的所有者。chown(2) 的包装器。

filehandle.close()

新增于:v10.0.0

  • 返回值:<Promise> 成功时返回 undefined

在等待句柄上任何挂起的操作完成后关闭文件句柄。

js
import { open } from 'node:fs/promises'

let filehandle
try {
  filehandle = await open('thefile.txt', 'r')
} finally {
  await filehandle?.close()
}

filehandle.createReadStream([options])

新增于:v16.11.0

options 可以包含 startend 值,用于读取文件的字节范围而不是整个文件。startend 都是包含的,从 0 开始计数,允许的值在 [0, Number.MAX_SAFE_INTEGER] 范围内。如果省略 startstartundefined,则 filehandle.createReadStream() 会从当前文件位置顺序读取。encoding 可以是 <Buffer> 接受的任何一个。

如果 FileHandle 指向仅支持阻塞读取的字符设备(例如键盘或声卡),则读取操作只有在数据可用时才会完成。这可能会阻止进程退出并阻止流自然关闭。

默认情况下,流会在销毁后发出 'close' 事件。将 emitClose 选项设置为 false 可以更改此行为。

js
import { open } from 'node:fs/promises'

const fd = await open('/dev/input/event0')
// 从某个字符设备创建流。
const stream = fd.createReadStream()
setTimeout(() => {
  stream.close() // 这可能无法关闭流。
  // 人工标记流结束,就像底层资源本身指示了文件结尾一样,允许流关闭。
  // 这不会取消挂起的读取操作,如果存在这样的操作,则进程可能仍然无法成功退出,
  // 直到它完成为止。
  stream.push(null)
  stream.read(0)
}, 100)

如果 autoClose 为 false,则即使发生错误,文件描述符也不会关闭。应用程序有责任关闭它并确保没有文件描述符泄漏。如果 autoClose 设置为 true(默认行为),则在 'error''end' 时,文件描述符将自动关闭。

读取 100 字节文件中最后 10 个字节的示例:

js
import { open } from 'node:fs/promises'

const fd = await open('sample.txt')
fd.createReadStream({ start: 90, end: 99 })

filehandle.createWriteStream([options])

[历史]

版本变更
v21.0.0, v20.10.0现在支持 flush 选项。
v16.11.0v16.11.0 版本新增

options 也可能包含一个 start 选项,允许从文件开头某个位置写入数据,允许的值在 [0, Number.MAX_SAFE_INTEGER] 范围内。修改文件而不是替换文件可能需要将 flags open 选项设置为 r+ 而不是默认的 rencoding 可以是 <Buffer> 接受的任何一个。

如果 autoClose 设置为 true(默认行为),则在 'error''finish' 时,文件描述符将自动关闭。如果 autoClose 为 false,则即使发生错误,文件描述符也不会关闭。应用程序有责任关闭它并确保没有文件描述符泄漏。

默认情况下,流将在销毁后发出 'close' 事件。将 emitClose 选项设置为 false 可以更改此行为。

filehandle.datasync()

新增于:v10.0.0

  • 返回值: <Promise> 成功时返回 undefined

强制将所有当前与文件关联的已排队的 I/O 操作强制到操作系统的同步 I/O 完成状态。有关详细信息,请参阅 POSIX fdatasync(2) 文档。

filehandle.sync 不同,此方法不会刷新已修改的元数据。

filehandle.fd

新增于:v10.0.0

filehandle.read(buffer, offset, length, position)

[历史]

版本变更
v21.0.0接受 bigint 值作为 position
v10.0.0新增于:v10.0.0
  • buffer <Buffer> | <TypedArray> | <DataView> 将用读取的文件数据填充的缓冲区。
  • offset <integer> 开始填充缓冲区的偏移量。默认值: 0
  • length <integer> 要读取的字节数。默认值: buffer.byteLength - offset
  • position <integer> | <bigint> | <null> 从文件中开始读取数据的位置。如果为 null-1,则将从当前文件位置读取数据,并且将更新位置。如果 position 是非负整数,则当前文件位置将保持不变。默认值: null
  • 返回值: <Promise> 成功时返回一个具有两个属性的对象:

读取文件中的数据并将其存储在给定的缓冲区中。

如果文件没有并发修改,则当读取的字节数为零时到达文件结尾。

filehandle.read([options])

[历史]

版本变更
v21.0.0接受 bigint 值作为 position
v13.11.0, v12.17.0新增于:v13.11.0, v12.17.0
  • options <对象>

    • buffer <Buffer> | <TypedArray> | <DataView> 一个将填充读取的文件数据的缓冲区。默认值: Buffer.alloc(16384)
    • offset <整数> 开始填充的缓冲区位置。默认值: 0
    • length <整数> 要读取的字节数。默认值: buffer.byteLength - offset
    • position <整数> | <bigint> | <null> 从文件中开始读取数据的位置。如果为 null-1,则将从当前文件位置读取数据,并且位置将更新。如果 position 是一个非负整数,则当前文件位置将保持不变。默认值: null
  • 返回值: <Promise> 成功时返回一个包含两个属性的对象:

从文件中读取数据并将其存储在给定的缓冲区中。

如果文件没有同时修改,则当读取的字节数为零时,将到达文件末尾。

filehandle.read(buffer[, options])

[历史]

版本变更
v21.0.0接受大整数作为 position
v18.2.0, v16.17.0新增于:v18.2.0, v16.17.0
  • buffer <Buffer> | <TypedArray> | <DataView> 将填充读取的文件数据的缓冲区。

  • options <Object>

    • offset <整数> 开始填充缓冲区的起始位置。默认值: 0
    • length <整数> 要读取的字节数。默认值: buffer.byteLength - offset
    • position <整数> | <大整数> | <null> 从文件中开始读取数据的位置。如果为 null-1,则从当前文件位置读取数据,并且位置将更新。如果 position 是一个非负整数,则当前文件位置将保持不变。默认值: null
  • 返回值: <Promise> 成功时返回一个包含两个属性的对象:

从文件中读取数据并将其存储在给定的缓冲区中。

如果文件没有并发修改,则当读取的字节数为零时,达到文件结尾。

filehandle.readableWebStream([options])

[历史]

版本变更
v20.0.0, v18.17.0添加了创建“bytes”流的选项。
v17.0.0v17.0.0 中添加

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

返回一个 ReadableStream,可用于读取文件数据。

如果此方法调用次数超过一次,或者在 FileHandle 关闭或正在关闭后调用,则会抛出错误。

js
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()
js
const { open } = require('node:fs/promises')

;(async () => {
  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)

新增于:v10.0.0

  • options <Object> | <string>

  • 返回值:<Promise> 成功读取文件内容后完成,如果未指定编码 (使用 options.encoding),则数据作为 <Buffer> 对象返回。否则,数据将是一个字符串。

异步读取文件的全部内容。

如果 options 是一个字符串,则它指定 encoding

<FileHandle> 必须支持读取。

如果在一个文件句柄上进行了一个或多个 filehandle.read() 调用,然后进行 filehandle.readFile() 调用,则数据将从当前位置读取到文件末尾。它并不总是从文件开头读取。

filehandle.readLines([options])

新增于:v18.11.0

创建 readline 接口并在文件中流式处理的便捷方法。有关选项,请参见 filehandle.createReadStream()

js
import { open } from 'node:fs/promises'

const file = await open('./some/file/to/read')

for await (const line of file.readLines()) {
  console.log(line)
}
js
const { open } = require('node:fs/promises')

;(async () => {
  const file = await open('./some/file/to/read')

  for await (const line of file.readLines()) {
    console.log(line)
  }
})()

filehandle.readv(buffers[, position])

新增于: v13.13.0, v12.17.0

从文件读取数据并写入 <ArrayBufferView> 数组

filehandle.stat([options])

[历史]

版本变更
v10.5.0接受一个额外的 options 对象来指定返回的数值是否应该为 BigInt。
v10.0.0新增于: v10.0.0

filehandle.sync()

新增于: v10.0.0

  • 返回值: <Promise> 成功时返回一个值为 undefined 的 Promise。

请求将打开的文件描述符的所有数据刷新到存储设备。具体的实现方式取决于操作系统和设备。有关更多详细信息,请参阅 POSIX fsync(2) 文档。

filehandle.truncate(len)

新增于:v10.0.0

截断文件。

如果文件大小大于 len 字节,则文件中只有前 len 字节会被保留。

以下示例保留文件的头四个字节:

js
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)

新增于:v10.0.0

更改由 <FileHandle> 引用的对象的 文件系统时间戳,然后在成功时以无参数的方式完成 Promise。

filehandle.write(buffer, offset[, length[, position]])

[历史]

版本变更
v14.0.0buffer 参数将不再强制转换不支持的输入为缓冲区。
v10.0.0新增于:v10.0.0
  • buffer <Buffer> | <TypedArray> | <DataView>
  • offset <整数> buffer 中写入数据开始的起始位置。
  • length <整数> 要写入的 buffer 中的字节数。默认值: buffer.byteLength - offset
  • position <整数> | <null> buffer 中的数据应写入的文件开头的偏移量。如果 position 不是一个数字,则数据将写入当前位置。有关更多详细信息,请参阅 POSIX pwrite(2) 文档。默认值: null
  • 返回值: <Promise>

buffer 写入文件。

Promise 将以包含两个属性的对象来完成:

在同一个文件上多次使用 filehandle.write() 而不等待 Promise 完成(或拒绝)是不安全的。对于这种情况,请使用 filehandle.createWriteStream()

在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略位置参数,并将数据始终追加到文件的末尾。

filehandle.write(buffer[, options])

新增于:v18.3.0, v16.17.0

buffer 写入文件。

类似于上面的 filehandle.write 函数,此版本接受可选的 options 对象。如果没有指定 options 对象,它将使用上述值作为默认值。

filehandle.write(string[, position[, encoding]])

[历史]

版本变更
v14.0.0string 参数不再强制将不支持的输入转换为字符串。
v10.0.0v10.0.0 中添加
  • string <字符串>
  • position <整数> | <null> 从文件开头开始写入 string 数据的偏移量。如果 position 不是一个 number,则数据将写入当前位置。有关更多详细信息,请参阅 POSIX pwrite(2) 文档。默认值: null
  • encoding <字符串> 预期的字符串编码。默认值: 'utf8'
  • 返回值: <Promise>

string 写入文件。如果 string 不是字符串,则 promise 将被拒绝并返回错误。

promise 将返回一个包含两个属性的对象:

在等待 promise 完成(或拒绝)之前,多次在同一文件上使用 filehandle.write() 是不安全的。对于这种情况,请使用 filehandle.createWriteStream()

在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略 position 参数,并始终将数据追加到文件的末尾。

filehandle.writeFile(data, options)

[历史]

版本变更
v15.14.0, v14.18.0data 参数支持 AsyncIterableIterableStream
v14.0.0data 参数不再强制将不支持的输入转换为字符串。
v10.0.0v10.0.0 中添加

异步地将数据写入文件,如果文件已存在则替换该文件。data 可以是字符串、缓冲区、 <AsyncIterable><Iterable> 对象。成功后,promise 将在没有任何参数的情况下完成。

如果 options 是一个字符串,则它指定 encoding

<FileHandle> 必须支持写入。

在等待 promise 完成(或拒绝)之前,对同一文件多次使用 filehandle.writeFile() 是不安全的。

如果在一个文件句柄上进行了一个或多个 filehandle.write() 调用,然后进行了一个 filehandle.writeFile() 调用,则数据将从当前位置写入到文件末尾。它并不总是从文件的开头写入。

filehandle.writev(buffers[, position])

新增于: v12.9.0

<ArrayBufferView> 数组写入文件。

Promise 将以包含两个属性的对象的形式完成:

在等待 Promise 完成(或拒绝)之前,对同一文件多次调用 writev() 是不安全的。

在 Linux 系统上,当文件以追加模式打开时,位置写入不起作用。内核会忽略 position 参数,并始终将数据追加到文件的末尾。

filehandle[Symbol.asyncDispose]()

新增于:v20.4.0, v18.18.0

[稳定性:1 - 实验性]

稳定性:1 稳定性:1 - 实验性

filehandle.close() 的别名。

fsPromises.access(path[, mode])

新增于:v10.0.0

测试用户对 path 指定的文件或目录的权限。mode 参数是一个可选整数,指定要执行的可访问性检查。mode 应为 fs.constants.F_OK 值或任何 fs.constants.R_OKfs.constants.W_OKfs.constants.X_OK 的按位或掩码(例如 fs.constants.W_OK | fs.constants.R_OK)。检查 文件访问常量 以获取 mode 的可能值。

如果可访问性检查成功,则 promise 就会 fulfilled,没有任何值。如果任何可访问性检查失败,则 promise 就会 rejected,并带有 <Error> 对象。以下示例检查当前进程是否可以读取和写入 /etc/passwd 文件。

js
import { access, constants } from 'node:fs/promises'

try {
  await access('/etc/passwd', constants.R_OK | constants.W_OK)
  console.log('可以访问')
} catch {
  console.error('无法访问')
}

不建议在调用 fsPromises.open() 之前使用 fsPromises.access() 检查文件的可访问性。这样做会引入竞争条件,因为其他进程可能会在这两个调用之间更改文件的状态。相反,用户代码应该直接打开/读取/写入文件,并在文件不可访问时处理引发的错误。

fsPromises.appendFile(path, data[, options])

[历史]

版本变更
v21.1.0, v20.10.0现在支持 flush 选项。
v10.0.0添加于:v10.0.0

异步地将数据追加到文件,如果文件不存在则创建该文件。data 可以是字符串或 <Buffer>

如果 options 是一个字符串,则它指定 encoding

mode 选项只影响新创建的文件。更多详情请参见 fs.open()

path 可以指定为一个已打开以进行追加操作的 <FileHandle>(使用 fsPromises.open())。

fsPromises.chmod(path, mode)

新增于:v10.0.0

更改文件的权限。

fsPromises.chown(path, uid, gid)

新增于:v10.0.0

更改文件的拥有者。

fsPromises.copyFile(src, dest[, mode])

[历史]

版本变更
v14.0.0flags 参数更改为 mode 并强制执行更严格的类型验证。
v10.0.0新增于:v10.0.0
  • src <字符串> | <Buffer> | <URL> 要复制的源文件名

  • dest <字符串> | <Buffer> | <URL> 复制操作的目标文件名

  • mode <整数> 可选的修饰符,用于指定复制操作的行为。可以创建一个由两个或多个值的按位或组成的掩码(例如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE默认值: 0

    • fs.constants.COPYFILE_EXCL: 如果 dest 已存在,则复制操作将失败。
    • fs.constants.COPYFILE_FICLONE: 复制操作将尝试创建一个写时复制 reflink。如果平台不支持写时复制,则使用回退复制机制。
    • fs.constants.COPYFILE_FICLONE_FORCE: 复制操作将尝试创建一个写时复制 reflink。如果平台不支持写时复制,则操作将失败。
  • 返回值: <Promise> 成功时返回 undefined

异步地将 src 复制到 dest。默认情况下,如果 dest 已存在,则会被覆盖。

不保证复制操作的原子性。如果在打开目标文件进行写入后发生错误,将尝试删除目标文件。

js
import { copyFile, constants } from 'node:fs/promises'

try {
  await copyFile('source.txt', 'destination.txt')
  console.log('source.txt 已复制到 destination.txt')
} catch {
  console.error('无法复制文件')
}

// 使用 COPYFILE_EXCL,如果 destination.txt 存在,则操作将失败。
try {
  await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL)
  console.log('source.txt 已复制到 destination.txt')
} catch {
  console.error('无法复制文件')
}

fsPromises.cp(src, dest[, options])

[历史]

版本变更
v22.3.0此 API 不再是实验性的。
v20.1.0, v18.17.0接受额外的 mode 选项,以指定复制行为,如同 fs.copyFile()mode 参数。
v17.6.0, v16.15.0接受额外的 verbatimSymlinks 选项,以指定是否对符号链接执行路径解析。
v16.7.0在 v16.7.0 版本中添加
  • src <字符串> | <URL> 要复制的源路径。

  • dest <字符串> | <URL> 要复制到的目标路径。

  • options <对象>

    • dereference <布尔值> 取消符号链接的引用。默认值: false

    • errorOnExist <布尔值>forcefalse 且目标存在时,抛出错误。默认值: false

    • filter <函数> 用于过滤复制的文件/目录的函数。返回 true 表示复制项目,返回 false 表示忽略它。忽略目录时,其所有内容也将被跳过。也可以返回一个解析为 truefalsePromise默认值: undefined

    • src <字符串> 要复制的源路径。

    • dest <字符串> 要复制到的目标路径。

    • 返回值: <布尔值> | <Promise> 可强制转换为 boolean 的值或一个 Promise,该 Promise 以此类值完成。

    • force <布尔值> 覆盖现有文件或目录。如果将此设置为 false 且目标存在,则复制操作将忽略错误。使用 errorOnExist 选项更改此行为。默认值: true

    • mode <整数> 复制操作的修饰符。默认值: 0。参见 fsPromises.copyFile()mode 标志。

    • preserveTimestamps <布尔值> 当为 true 时,将保留来自 src 的时间戳。默认值: false

    • recursive <布尔值> 递归复制目录 默认值: false

    • verbatimSymlinks <布尔值> 当为 true 时,将跳过符号链接的路径解析。默认值: false

  • 返回值: <Promise> 成功时完成并返回 undefined

异步地将整个目录结构从 src 复制到 dest,包括子目录和文件。

将目录复制到另一个目录时,不支持 glob 模式,行为类似于 cp dir1/ dir2/

fsPromises.glob(pattern[, options])

[历史]

版本变更
v22.2.0添加对 withFileTypes 选项的支持。
v22.0.0v22.0.0 版本中添加

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

  • pattern <字符串> | <字符串数组>

  • options <对象>

    • cwd <字符串> 当前工作目录。默认值: process.cwd()
    • exclude <函数> 用于过滤文件/目录的函数。返回 true 表示排除该项,返回 false 表示包含该项。默认值: undefined
    • withFileTypes <布尔值> 如果 glob 应该将路径作为 Dirents 返回,则为 true,否则为 false默认值: false
  • 返回值: <异步迭代器> 一个异步迭代器,它会生成与模式匹配的文件路径。

js
import { glob } from 'node:fs/promises'

for await (const entry of glob('**/*.js')) console.log(entry)
js
const { glob } = require('node:fs/promises')

;(async () => {
  for await (const entry of glob('**/*.js')) console.log(entry)
})()

fsPromises.lchmod(path, mode)

已弃用自: v10.0.0

更改符号链接的权限。

此方法仅在 macOS 上实现。

fsPromises.lchown(path, uid, gid)

[历史]

版本变更
v10.6.0此 API 现已不再弃用。
v10.0.0新增于: v10.0.0

更改符号链接的所有权。

fsPromises.lutimes(path, atime, mtime)

新增于: v14.5.0, v12.19.0

以与 fsPromises.utimes() 相同的方式更改文件的访问时间和修改时间,区别在于,如果路径指向符号链接,则不会取消符号链接的引用:而是更改符号链接本身的时间戳。

fsPromises.link(existingPath, newPath)

新增于:v10.0.0

existingPath 创建一个指向 newPath 的新链接。更多细节请参考 POSIX link(2) 文档。

fsPromises.lstat(path[, options])

[历史]

版本变更
v10.5.0接受额外的 options 对象来指定返回的数值是否为大整数。
v10.0.0新增于:v10.0.0

除非 path 指向一个符号链接,否则等同于 fsPromises.stat(),在这种情况下,会对链接本身进行 stat 操作,而不是它指向的文件。更多细节请参考 POSIX lstat(2) 文档。

fsPromises.mkdir(path[, options])

新增于:v10.0.0

异步创建目录。

可选的 options 参数可以是一个整数,指定 mode(权限和粘滞位),或者是一个对象,包含 mode 属性和 recursive 属性,指示是否应该创建父目录。当 path 指向已存在的目录时,只有当 recursivefalse 时,fsPromises.mkdir() 才会拒绝。

js
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)
}
js
const { mkdir } = require('node:fs/promises')
const { join } = require('node:path')

async function makeDirectory() {
  const projectFolder = join(__dirname, 'test', 'project')
  const dirCreation = await mkdir(projectFolder, { recursive: true })

  console.log(dirCreation)
  return dirCreation
}

makeDirectory().catch(console.error)

fsPromises.mkdtemp(prefix[, options])

[历史]

版本变更
v20.6.0, v18.19.0prefix 参数现在接受缓冲区和 URL。
v16.5.0, v14.18.0prefix 参数现在接受空字符串。
v10.0.0v10.0.0 中添加

创建一个唯一的临时目录。通过在提供的 prefix 的末尾附加六个随机字符来生成唯一的目录名称。由于平台不一致,请避免在 prefix 中使用尾随 X 字符。某些平台(特别是 BSD)可能会返回超过六个随机字符,并用随机字符替换 prefix 中尾随的 X 字符。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定要使用的字符编码。

js
import { mkdtemp } from 'node:fs/promises'
import { join } from 'node:path'
import { tmpdir } from 'node:os'

try {
  await mkdtemp(join(tmpdir(), 'foo-'))
} catch (err) {
  console.error(err)
}

fsPromises.mkdtemp() 方法会将六个随机选择的字符直接附加到 prefix 字符串。例如,给定一个目录 /tmp,如果目的是在 /tmp 内部 创建一个临时目录,则 prefix 必须以平台特定的路径分隔符结尾 (require('node:path').sep)。

fsPromises.open(path, flags[, mode])

[历史]

版本变更
v11.1.0flags 参数现在可选,默认为 'r'
v10.0.0v10.0.0 中添加

打开一个 <FileHandle>

有关详细信息,请参阅 POSIX open(2) 文档。

某些字符(< > : " / \ | ? *)在 Windows 下是保留字符,如 命名文件、路径和命名空间 中所述。在 NTFS 下,如果文件名包含冒号,则 Node.js 将打开一个文件系统流,如 此 MSDN 页面 中所述。

fsPromises.opendir(path[, options])

[历史]

版本变更
v20.1.0, v18.17.0添加了 recursive 选项。
v13.1.0, v12.16.0引入了 bufferSize 选项。
v12.12.0v12.12.0 中添加

异步打开一个目录以进行迭代扫描。有关更多详细信息,请参阅 POSIX opendir(3) 文档。

创建一个 <fs.Dir>,其中包含从目录读取和清理目录的所有其他函数。

encoding 选项在打开目录和后续读取操作时设置 path 的编码。

异步迭代示例:

js
import { opendir } from 'node:fs/promises'

try {
  const dir = await opendir('./')
  for await (const dirent of dir) console.log(dirent.name)
} catch (err) {
  console.error(err)
}

使用异步迭代器时,迭代器退出后, <fs.Dir> 对象将自动关闭。

fsPromises.readdir(path[, options])

[历史]

版本变更
v20.1.0, v18.17.0添加了 recursive 选项。
v10.11.0添加了新选项 withFileTypes
v10.0.0在 v10.0.0 中添加

读取目录的内容。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定用于文件名的字符编码。如果 encoding 设置为 'buffer',则返回的文件名将作为 <Buffer> 对象传递。

如果将 options.withFileTypes 设置为 true,则返回的数组将包含 <fs.Dirent> 对象。

js
import { readdir } from 'node:fs/promises'

try {
  const files = await readdir(path)
  for (const file of files) console.log(file)
} catch (err) {
  console.error(err)
}

fsPromises.readFile(path[, options])

[历史]

版本变更
v15.2.0, v14.17.0options 参数可以包含 AbortSignal 以中止正在进行的 readFile 请求。
v10.0.0新增于:v10.0.0

异步读取文件的全部内容。

如果未指定编码(使用 options.encoding),则数据将作为 <Buffer> 对象返回。否则,数据将为字符串。

如果 options 是一个字符串,则它指定编码。

path 是一个目录时,fsPromises.readFile() 的行为是平台相关的。在 macOS、Linux 和 Windows 上,promise 将被拒绝并返回错误。在 FreeBSD 上,将返回目录内容的表示。

读取位于运行代码同一目录下的 package.json 文件的示例:

js
import { readFile } from 'node:fs/promises'
try {
  const filePath = new URL('./package.json', import.meta.url)
  const contents = await readFile(filePath, { encoding: 'utf8' })
  console.log(contents)
} catch (err) {
  console.error(err.message)
}
js
const { readFile } = require('node:fs/promises')
const { resolve } = require('node:path')
async function logFile() {
  try {
    const filePath = resolve('./package.json')
    const contents = await readFile(filePath, { encoding: 'utf8' })
    console.log(contents)
  } catch (err) {
    console.error(err.message)
  }
}
logFile()

可以使用 <AbortSignal> 中止正在进行的 readFile。如果请求被中止,则返回的 promise 将被 AbortError 拒绝:

js
import { readFile } from 'node:fs/promises'

try {
  const controller = new AbortController()
  const { signal } = controller
  const promise = readFile(fileName, { signal })

  // 在 promise 结算前中止请求。
  controller.abort()

  await promise
} catch (err) {
  // 当请求被中止时 - err 是一个 AbortError
  console.error(err)
}

中止正在进行的请求不会中止单个操作系统请求,而是中止 fs.readFile 执行的内部缓冲。

任何指定的 <FileHandle> 都必须支持读取。

fsPromises.readlink(path[, options])

新增于:v10.0.0

读取 path 指定的符号链接的内容。更多细节请参考 POSIX readlink(2) 文档。成功时,promise 将返回 linkString

可选的 options 参数可以是一个字符串,指定编码,或者是一个包含 encoding 属性的对象,用于指定返回的链接路径的字符编码。如果 encoding 设置为 'buffer',则返回的链接路径将作为 <Buffer> 对象传递。

fsPromises.realpath(path[, options])

新增于:v10.0.0

使用与 fs.realpath.native() 函数相同的语义确定 path 的实际位置。

仅支持可以转换为 UTF8 字符串的路径。

可选的 options 参数可以是一个字符串,指定编码,或者是一个对象,其中包含一个 encoding 属性,用于指定路径使用的字符编码。如果将 encoding 设置为 'buffer',则返回的路径将作为 <Buffer> 对象传递。

在 Linux 系统上,当 Node.js 链接到 musl libc 时,必须将 procfs 文件系统挂载到 /proc 上,此函数才能正常工作。Glibc 没有此限制。

fsPromises.rename(oldPath, newPath)

新增于: v10.0.0

oldPath 重命名为 newPath

fsPromises.rmdir(path[, options])

[历史]

版本变更
v16.0.0path 为文件时使用 fsPromises.rmdir(path, { recursive: true }) 将不再允许,并在 Windows 上返回 ENOENT 错误,在 POSIX 上返回 ENOTDIR 错误。
v16.0.0path 不存在时使用 fsPromises.rmdir(path, { recursive: true }) 将不再允许,并将返回 ENOENT 错误。
v16.0.0recursive 选项已弃用,使用它会触发弃用警告。
v14.14.0recursive 选项已弃用,请改用 fsPromises.rm
v13.3.0, v12.16.0maxBusyTries 选项已重命名为 maxRetries,其默认值为 0。emfileWait 选项已被移除,EMFILE 错误使用与其他错误相同的重试逻辑。retryDelay 选项现在已支持。ENFILE 错误现在会重试。
v12.10.0recursivemaxBusyTriesemfileWait 选项现在已支持。
v10.0.0新增于: v10.0.0
  • path <string> | <Buffer> | <URL>

  • options <Object>

    • maxRetries <integer> 如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 将使用线性回退等待(每次尝试等待时间增加 retryDelay 毫秒)重试操作。此选项表示重试次数。如果 recursive 选项不是 true,则忽略此选项。默认值: 0
    • recursive <boolean> 如果为 true,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值: false已弃用。
    • retryDelay <integer> 重试之间等待的时间(毫秒)。如果 recursive 选项不是 true,则忽略此选项。默认值: 100
  • 返回值: <Promise> 成功时返回 undefined

删除由 path 指定的目录。

在文件(而不是目录)上使用 fsPromises.rmdir() 会导致 promise 被拒绝,并在 Windows 上返回 ENOENT 错误,在 POSIX 上返回 ENOTDIR 错误。

要获得类似于 rm -rf Unix 命令的行为,请使用 fsPromises.rm() 并设置选项 { recursive: true, force: true }

fsPromises.rm(path[, options])

新增于: v14.14.0

  • path <string> | <Buffer> | <URL>

  • options <Object>

    • force <boolean> 当值为 true 时,如果 path 不存在,则忽略异常。默认值: false
    • maxRetries <integer> 如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 将重试操作,每次尝试的线性回退等待时间为 retryDelay 毫秒。此选项表示重试次数。如果 recursive 选项不是 true,则忽略此选项。默认值: 0
    • recursive <boolean> 如果为 true,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值: false
    • retryDelay <integer> 重试之间等待的时间(毫秒)。如果 recursive 选项不是 true,则忽略此选项。默认值: 100
  • 返回值: <Promise> 成功时返回 undefined

删除文件和目录(基于标准 POSIX rm 实用程序)。

fsPromises.stat(path[, options])

[历史]

版本变更
v10.5.0接受额外的 options 对象来指定返回的数值是否应为 BigInt。
v10.0.0新增于:v10.0.0

fsPromises.statfs(path[, options])

新增于:v19.6.0, v18.15.0

fsPromises.symlink(target, path[, type])

[历史]

版本变更
v19.0.0如果 type 参数为 null 或省略,Node.js 将自动检测 target 类型并自动选择 dirfile
v10.0.0新增于:v10.0.0

创建符号链接。

type 参数仅在 Windows 平台上使用,可以是 'dir''file''junction' 之一。如果 type 参数为 null,Node.js 将自动检测 target 类型并使用 'file''dir'。如果 target 不存在,将使用 'file'。Windows 链接点要求目标路径为绝对路径。使用 'junction' 时,target 参数将自动规范化为绝对路径。NTFS 卷上的链接点只能指向目录。

fsPromises.truncate(path[, len])

新增于: v10.0.0

path指向的内容截断(缩短或扩展长度)为len个字节。

fsPromises.unlink(path)

新增于: v10.0.0

如果path指向符号链接,则删除链接,而不影响该链接指向的文件或目录。如果path指向的不是符号链接的文件路径,则删除该文件。有关详细信息,请参阅 POSIX unlink(2) 文档。

fsPromises.utimes(path, atime, mtime)

新增于:v10.0.0

更改由 path 引用的对象的系统时间戳。

atimemtime 参数遵循以下规则:

  • 值可以是表示 Unix 纪元时间的数字、Date 对象或类似 '123456789.0' 的数字字符串。
  • 如果该值无法转换为数字,或者为 NaNInfinity-Infinity,则会抛出 Error

fsPromises.watch(filename[, options])

新增于:v15.9.0, v14.18.0

返回一个异步迭代器,用于监视 filename 上的更改,其中 filename 是文件或目录。

js
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])

[历史]

版本变更
v21.0.0, v20.10.0现在支持 flush 选项。
v15.14.0, v14.18.0data 参数现在支持 AsyncIterableIterableStream
v15.2.0, v14.17.0options 参数可以包含一个 AbortSignal 来中止正在进行的 writeFile 请求。
v14.0.0data 参数不再强制将不支持的输入转换为字符串。
v10.0.0新增于:v10.0.0

异步地将数据写入文件,如果文件已存在则替换该文件。data 可以是字符串、缓冲区、 <AsyncIterable><Iterable> 对象。

如果 data 是缓冲区,则忽略 encoding 选项。

如果 options 是字符串,则它指定编码。

mode 选项仅影响新创建的文件。有关更多详细信息,请参阅 fs.open()

任何指定的 <FileHandle> 都必须支持写入。

在等待 promise 完成之前,多次在同一文件上使用 fsPromises.writeFile() 是不安全的。

fsPromises.readFile 类似 - fsPromises.writeFile 是一种便捷方法,它在内部执行多个 write 调用来写入传递给它的缓冲区。对于性能敏感的代码,请考虑使用 fs.createWriteStream()filehandle.createWriteStream()

可以使用 <AbortSignal> 来取消 fsPromises.writeFile()。取消是“尽力而为”的,一些数据可能仍然会被写入。

js
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 })

  // 在 promise 完成之前中止请求。
  controller.abort()

  await promise
} catch (err) {
  // 当请求被中止时 - err 是一个 AbortError
  console.error(err)
}

中止正在进行的请求不会中止单个操作系统请求,而是中止 fs.writeFile 执行的内部缓冲。

fsPromises.constants

新增于:v18.4.0, v16.17.0

返回一个包含常用文件系统操作常量的对象。此对象与 fs.constants 相同。更多详情请参见 文件系统常量

回调 API

回调 API 异步执行所有操作,不会阻塞事件循环,然后在完成或出错时调用回调函数。

回调 API 使用底层的 Node.js 线程池在事件循环线程之外执行文件系统操作。这些操作不是同步的或线程安全的。当对同一个文件执行多个并发修改时必须小心,否则可能会导致数据损坏。

fs.access(path[, mode], callback)

[历史]

版本变更
v20.8.0直接位于 fs 上的常量 fs.F_OKfs.R_OKfs.W_OKfs.X_OK 已弃用。
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v6.3.0诸如 fs.R_OK 等直接位于 fs 上的常量已移至 fs.constants,作为软弃用。因此,对于 Node.js < v6.3.0,使用 fs 访问这些常量,或者使用 `(fs.constants
v0.11.15新增于:v0.11.15

测试用户对 path 指定的文件或目录的权限。mode 参数是一个可选的整数,指定要执行的可访问性检查。mode 应为 fs.constants.F_OK 值或由 fs.constants.R_OKfs.constants.W_OKfs.constants.X_OK 中任意一个按位或组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK)。检查 文件访问常量 以了解 mode 的可能值。

最后一个参数 callback 是一个回调函数,它会使用一个可能的错误参数调用。如果任何可访问性检查失败,则错误参数将是一个 Error 对象。以下示例检查 package.json 是否存在,以及它是否可读或可写。

js
import { access, constants } from 'node:fs'

const file = 'package.json'

// 检查文件是否存在于当前目录中。
access(file, constants.F_OK, err => {
  console.log(`${file} ${err ? '不存在' : '存在'}`)
})

// 检查文件是否可读。
access(file, constants.R_OK, err => {
  console.log(`${file} ${err ? '不可读' : '可读'}`)
})

// 检查文件是否可写。
access(file, constants.W_OK, err => {
  console.log(`${file} ${err ? '不可写' : '可写'}`)
})

// 检查文件是否可读和可写。
access(file, constants.R_OK | constants.W_OK, err => {
  console.log(`${file} ${err ? '不是' : '是'} 可读和可写的`)
})

不要在调用 fs.open()fs.readFile()fs.writeFile() 之前使用 fs.access() 来检查文件的可访问性。这样做会引入竞争条件,因为其他进程可能会在这两个调用之间更改文件的状态。相反,用户代码应该直接打开/读取/写入文件,并在文件不可访问时处理引发的错误。

写入 (不推荐)

js
import { access, open, close } from 'node:fs'

access('myfile', err => {
  if (!err) {
    console.error('myfile 已存在')
    return
  }

  open('myfile', 'wx', (err, fd) => {
    if (err) throw err

    try {
      writeMyData(fd)
    } finally {
      close(fd, err => {
        if (err) throw err
      })
    }
  })
})

写入 (推荐)

js
import { open, close } from 'node:fs'

open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile 已存在')
      return
    }

    throw err
  }

  try {
    writeMyData(fd)
  } finally {
    close(fd, err => {
      if (err) throw err
    })
  }
})

读取 (不推荐)

js
import { access, open, close } from 'node:fs'
access('myfile', err => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile 不存在')
      return
    }

    throw err
  }

  open('myfile', 'r', (err, fd) => {
    if (err) throw err

    try {
      readMyData(fd)
    } finally {
      close(fd, err => {
        if (err) throw err
      })
    }
  })
})

读取 (推荐)

js
import { open, close } from 'node:fs'

open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile 不存在')
      return
    }

    throw err
  }

  try {
    readMyData(fd)
  } finally {
    close(fd, err => {
      if (err) throw err
    })
  }
})

上面的“不推荐”示例检查可访问性,然后使用文件;“推荐”示例更好,因为它们直接使用文件并处理错误(如果有)。

一般来说,只有在不直接使用文件时才检查文件的可访问性,例如,当它的可访问性是来自另一个进程的信号时。

在 Windows 上,目录上的访问控制策略 (ACL) 可能会限制对文件或目录的访问。但是,fs.access() 函数不检查 ACL,因此即使 ACL 限制用户读取或写入它,也可能报告路径是可访问的。

fs.appendFile(path, data[, options], callback)

[历史记录]

版本变更
v21.1.0, v20.10.0现在支持 flush 选项。
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v7.0.0传递的 options 对象将永远不会被修改。
v5.0.0file 参数现在可以是文件描述符。
v0.6.7v0.6.7 版本中添加

异步地将数据追加到文件,如果文件尚不存在则创建该文件。data 可以是字符串或 <Buffer>

mode 选项仅影响新创建的文件。有关更多详细信息,请参阅 fs.open()

js
import { appendFile } from 'node:fs'

appendFile('message.txt', 'data to append', err => {
  if (err) throw err
  console.log('The "data to append" was appended to file!')
})

如果 options 是一个字符串,则它指定编码:

js
import { appendFile } from 'node:fs'

appendFile('message.txt', 'data to append', 'utf8', callback)

path 可以指定为已打开以进行追加(使用 fs.open()fs.openSync())的数字文件描述符。文件描述符不会自动关闭。

js
import { open, close, appendFile } from 'node:fs'

function closeFd(fd) {
  close(fd, err => {
    if (err) throw err
  })
}

open('message.txt', 'a', (err, fd) => {
  if (err) throw err

  try {
    appendFile(fd, 'data to append', 'utf8', err => {
      closeFd(fd)
      if (err) throw err
    })
  } catch (err) {
    closeFd(fd)
    throw err
  }
})

fs.chmod(path, mode, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再可选。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再可选。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.1.30v0.1.30 版本中添加

异步更改文件的权限。完成回调除了可能的异常之外,没有其他参数。

更多详情请参阅 POSIX chmod(2) 文档。

js
import { chmod } from 'node:fs'

chmod('my_file.txt', 0o775, err => {
  if (err) throw err
  console.log('文件 "my_file.txt" 的权限已更改!')
})

文件模式

fs.chmod()fs.chmodSync() 方法中使用的 mode 参数是一个数值位掩码,使用以下常量的逻辑或运算创建:

常量八进制描述
fs.constants.S_IRUSR0o400所有者可读
fs.constants.S_IWUSR0o200所有者可写
fs.constants.S_IXUSR0o100所有者可执行/搜索
fs.constants.S_IRGRP0o40组可读
fs.constants.S_IWGRP0o20组可写
fs.constants.S_IXGRP0o10组可执行/搜索
fs.constants.S_IROTH0o4其他用户可读
fs.constants.S_IWOTH0o2其他用户可写
fs.constants.S_IXOTH0o1其他用户可执行/搜索

构造 mode 的一种更简单的方法是使用三个八进制数字的序列(例如 765)。最左边的数字(示例中为 7)指定文件所有者的权限。中间的数字(示例中为 6)指定组的权限。最右边的数字(示例中为 5)指定其他用户的权限。

数字描述
7可读、可写和可执行
6可读和可写
5可读和可执行
4只读
3可写和可执行
2只写
1只执行
0无权限

例如,八进制值 0o765 表示:

  • 所有者可以读取、写入和执行文件。
  • 组可以读取和写入文件。
  • 其他用户可以读取和执行文件。

当使用原始数字作为文件模式时,任何大于 0o777 的值都可能导致平台特定的行为,这些行为不被保证一致地工作。因此,fs.constants 中不公开诸如 S_ISVTXS_ISGIDS_ISUID 之类的常量。

警告:在 Windows 上,只有写入权限可以更改,并且组、所有者或其他用户的权限之间的区别未实现。

fs.chown(path, uid, gid, callback)

[历史]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.1.97v0.1.97 版本中添加

异步更改文件的拥有者和组。完成回调除了可能的异常之外,不会给出任何参数。

请参阅 POSIX chown(2) 文档以了解更多详细信息。

fs.close(fd[, callback])

[历史]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v15.9.0, v14.17.0如果没有提供回调,现在将使用默认回调。
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它将发出带有 ID DEP0013 的弃用警告。
v0.0.2新增于:v0.0.2

关闭文件描述符。完成回调除了可能的异常之外,不会接收任何其他参数。

对任何当前正通过任何其他 fs 操作使用的文件描述符 (fd) 调用 fs.close() 可能会导致未定义的行为。

有关更多详细信息,请参阅 POSIX close(2) 文档。

fs.copyFile(src, dest[, mode], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v14.0.0flags 参数更改为 mode 并实施了更严格的类型验证。
v8.5.0v8.5.0 版本中添加

异步地将 src 复制到 dest。默认情况下,如果 dest 已存在,则会被覆盖。回调函数除了可能的异常之外,不会接收任何其他参数。Node.js 并不保证复制操作的原子性。如果在打开目标文件写入后发生错误,Node.js 将尝试删除目标文件。

mode 是一个可选整数,用于指定复制操作的行为。可以创建一个掩码,该掩码由两个或多个值的按位 OR 组成(例如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE)。

  • fs.constants.COPYFILE_EXCL: 如果 dest 已存在,则复制操作将失败。
  • fs.constants.COPYFILE_FICLONE: 复制操作将尝试创建写入时复制的 reflink。如果平台不支持写入时复制,则使用回退复制机制。
  • fs.constants.COPYFILE_FICLONE_FORCE: 复制操作将尝试创建写入时复制的 reflink。如果平台不支持写入时复制,则操作将失败。
js
import { copyFile, constants } from 'node:fs'

function callback(err) {
  if (err) throw err
  console.log('source.txt 已复制到 destination.txt')
}

// destination.txt 将被创建或默认覆盖。
copyFile('source.txt', 'destination.txt', callback)

// 使用 COPYFILE_EXCL,如果 destination.txt 存在,则操作将失败。
copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback)

fs.cp(src, dest[, options], callback)

[历史记录]

版本变更
v22.3.0此 API 不再是实验性的。
v20.1.0, v18.17.0接受额外的 mode 选项,以指定复制行为,作为 fs.copyFile()mode 参数。
v18.0.0将无效的回调传递给 callback 参数现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v17.6.0, v16.15.0接受额外的 verbatimSymlinks 选项,以指定是否对符号链接执行路径解析。
v16.7.0新增于:v16.7.0
  • src <字符串> | <URL> 要复制的源路径。

  • dest <字符串> | <URL> 要复制到的目标路径。

  • options <对象>

    • dereference <布尔值> 取消符号链接的引用。默认值: false

    • errorOnExist <布尔值>forcefalse 且目标存在时,抛出错误。默认值: false

    • filter <函数> 用于过滤已复制文件/目录的函数。返回 true 表示复制项目,返回 false 表示忽略它。忽略目录时,其所有内容也将被跳过。也可以返回一个解析为 truefalsePromise默认值: undefined

    • src <字符串> 要复制的源路径。

    • dest <字符串> 要复制到的目标路径。

    • 返回值: <布尔值> | <Promise> 一个可强制转换为 boolean 的值或一个以此值为结果的 Promise

    • force <布尔值> 覆盖现有文件或目录。如果将此设置为 false 且目标存在,则复制操作将忽略错误。使用 errorOnExist 选项更改此行为。默认值: true

    • mode <整数> 复制操作的修饰符。默认值: 0。参见 fs.copyFile()mode 标志。

    • preserveTimestamps <布尔值> 当为 true 时,将保留来自 src 的时间戳。默认值: false

    • recursive <布尔值> 递归复制目录 默认值: false

    • verbatimSymlinks <布尔值> 当为 true 时,将跳过符号链接的路径解析。默认值: false

  • callback <函数>

异步地将整个目录结构从 src 复制到 dest,包括子目录和文件。

将目录复制到另一个目录时,不支持通配符,行为类似于 cp dir1/ dir2/

fs.createReadStream(path[, options])

[历史记录]

版本变更
v16.10.0如果提供了 fd,则 fs 选项不需要 open 方法。
v16.10.0如果 autoClosefalse,则 fs 选项不需要 close 方法。
v15.5.0添加对 AbortSignal 的支持。
v15.4.0fd 选项接受 FileHandle 参数。
v14.0.0emitClose 默认值更改为 true
v13.6.0, v12.17.0fs 选项允许覆盖使用的 fs 实现。
v12.10.0启用 emitClose 选项。
v11.0.0startend 施加新的限制,在无法合理处理输入值的情况下抛出更合适的错误。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0传递的 options 对象将永远不会被修改。
v2.3.0传递的 options 对象现在可以是字符串。
v0.1.31新增于:v0.1.31

options 可以包含 startend 值,用于读取文件的一部分字节而不是整个文件。startend 都是包含的,从 0 开始计数,允许的值在 [0, Number.MAX_SAFE_INTEGER] 范围内。如果指定了 fd 并省略或未定义 start,则 fs.createReadStream() 会从当前文件位置顺序读取。encoding 可以是 <Buffer> 接受的任何一种。

如果指定了 fdReadStream 将忽略 path 参数并将使用指定的文件描述符。这意味着不会发出 'open' 事件。fd 应该是阻塞的;非阻塞 fd 应该传递给 <net.Socket>

如果 fd 指向仅支持阻塞读取的字符设备(例如键盘或声卡),则读取操作在数据可用之前不会完成。这可能会阻止进程退出和流自然关闭。

默认情况下,流将在销毁后发出 'close' 事件。将 emitClose 选项设置为 false 以更改此行为。

通过提供 fs 选项,可以覆盖 openreadclose 的相应 fs 实现。提供 fs 选项时,需要覆盖 read。如果没有提供 fd,还需要覆盖 open。如果 autoClosetrue,还需要覆盖 close

js
import { createReadStream } from 'node:fs'

// 从某个字符设备创建流。
const stream = createReadStream('/dev/input/event0')
setTimeout(() => {
  stream.close() // 这可能无法关闭流。
  // 人工标记流结束,就像底层资源本身指示文件结尾一样,允许流关闭。
  // 这不会取消挂起的读取操作,如果存在这样的操作,则该进程可能仍然无法成功退出,
  // 直到它完成。
  stream.push(null)
  stream.read(0)
}, 100)

如果 autoClose 为 false,则即使发生错误,文件描述符也不会关闭。应用程序有责任关闭它并确保没有文件描述符泄漏。如果 autoClose 设置为 true(默认行为),则在 'error''end' 时,文件描述符将自动关闭。

mode 设置文件模式(权限和粘滞位),但仅当创建文件时才如此。

一个读取长度为 100 字节的文件的最后 10 个字节的示例:

js
import { createReadStream } from 'node:fs'

createReadStream('sample.txt', { start: 90, end: 99 })

如果 options 是一个字符串,则它指定编码。

fs.createWriteStream(path[, options])

[历史]

版本变更
v21.0.0, v20.10.0现在支持 flush 选项。
v16.10.0如果提供了 fd,则 fs 选项不需要 open 方法。
v16.10.0如果 autoClosefalse,则 fs 选项不需要 close 方法。
v15.5.0添加对 AbortSignal 的支持。
v15.4.0fd 选项接受 FileHandle 参数。
v14.0.0emitClose 默认值更改为 true
v13.6.0, v12.17.0fs 选项允许覆盖使用的 fs 实现。
v12.10.0启用 emitClose 选项。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0传递的 options 对象将永远不会被修改。
v5.5.0现在支持 autoClose 选项。
v2.3.0传递的 options 对象现在可以是字符串。
v0.1.31v0.1.31 版本中添加

options 还可以包含一个 start 选项,允许在文件开头的某个位置写入数据,允许的值在 [0, Number.MAX_SAFE_INTEGER] 范围内。修改文件而不是替换文件可能需要将 flags 选项设置为 r+ 而不是默认的 wencoding 可以是 <Buffer> 接受的任何一个。

如果 autoClose 设置为 true(默认行为),则在 'error''finish' 时,文件描述符将自动关闭。如果 autoClose 为 false,则即使发生错误,文件描述符也不会关闭。应用程序有责任关闭它并确保没有文件描述符泄漏。

默认情况下,流将在销毁后发出 'close' 事件。将 emitClose 选项设置为 false 以更改此行为。

通过提供 fs 选项,可以覆盖 openwritewritevclose 的相应 fs 实现。在没有 writev() 的情况下覆盖 write() 会降低性能,因为某些优化(_writev())将被禁用。提供 fs 选项时,至少需要覆盖 writewritev 之一。如果没有提供 fd 选项,还需要覆盖 open。如果 autoClosetrue,还需要覆盖 close

<fs.ReadStream> 一样,如果指定了 fd,则 <fs.WriteStream> 将忽略 path 参数并使用指定的文件描述符。这意味着不会发出 'open' 事件。fd 应该是阻塞的;非阻塞 fd 应该传递给 <net.Socket>

如果 options 是一个字符串,则它指定编码。

fs.exists(path, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v1.0.0自 v1.0.0 起弃用
v0.0.2在 v0.0.2 中添加

[稳定性: 0 - 已弃用]

稳定性: 0 稳定性: 0 - 已弃用:请改用 fs.stat()fs.access()

通过检查文件系统来测试给定 path 中的元素是否存在。然后使用 true 或 false 调用 callback 参数:

js
import { exists } from 'node:fs'

exists('/etc/passwd', e => {
  console.log(e ? '它存在' : '没有 passwd!')
})

此回调的参数与其他 Node.js 回调不一致。 通常,Node.js 回调的第一个参数是 err 参数,之后可以选择其他参数。fs.exists() 回调只有一个布尔参数。这就是推荐使用 fs.access() 而不是 fs.exists() 的原因之一。

如果 path 是符号链接,则会跟随它。因此,如果 path 存在但指向不存在的元素,则回调将接收值 false

不建议使用 fs.exists() 检查文件是否存在,然后再调用 fs.open()fs.readFile()fs.writeFile()。这样做会引入竞争条件,因为其他进程可能会在这两个调用之间更改文件的状态。相反,用户代码应该直接打开/读取/写入文件,并在文件不存在时处理引发的错误。

写入 (不推荐)

js
import { exists, open, close } from 'node:fs'

exists('myfile', e => {
  if (e) {
    console.error('myfile 已存在')
  } else {
    open('myfile', 'wx', (err, fd) => {
      if (err) throw err

      try {
        writeMyData(fd)
      } finally {
        close(fd, err => {
          if (err) throw err
        })
      }
    })
  }
})

写入 (推荐)

js
import { open, close } from 'node:fs'
open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile 已存在')
      return
    }

    throw err
  }

  try {
    writeMyData(fd)
  } finally {
    close(fd, err => {
      if (err) throw err
    })
  }
})

读取 (不推荐)

js
import { open, close, exists } from 'node:fs'

exists('myfile', e => {
  if (e) {
    open('myfile', 'r', (err, fd) => {
      if (err) throw err

      try {
        readMyData(fd)
      } finally {
        close(fd, err => {
          if (err) throw err
        })
      }
    })
  } else {
    console.error('myfile 不存在')
  }
})

读取 (推荐)

js
import { open, close } from 'node:fs'

open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile 不存在')
      return
    }

    throw err
  }

  try {
    readMyData(fd)
  } finally {
    close(fd, err => {
      if (err) throw err
    })
  }
})

上面“不推荐”的示例检查是否存在,然后使用该文件;“推荐”的示例更好,因为它们直接使用该文件并处理错误(如果有)。

通常,只有在不会直接使用文件时才检查文件是否存在,例如,当它的存在是来自另一个进程的信号时。

fs.fchmod(fd, mode, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它会发出带有 ID DEP0013 的弃用警告。
v0.4.7新增于:v0.4.7

设置文件的权限。完成回调除了可能的异常之外,没有其他参数。

有关更多详细信息,请参阅 POSIX fchmod(2) 文档。

fs.fchown(fd, uid, gid, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.4.7v0.4.7 版本中添加

设置文件的所有者。除了可能的异常之外,不会向完成回调传递任何参数。

有关更多详细信息,请参阅 POSIX fchown(2) 文档。

fs.fdatasync(fd, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它会发出一个带有 ID DEP0013 的弃用警告。
v0.1.96新增于:v0.1.96

强制所有当前与文件关联的已排队的 I/O 操作进入操作系统的同步 I/O 完成状态。有关详细信息,请参阅 POSIX fdatasync(2) 文档。完成回调除了可能的异常外,不会给出任何其他参数。

fs.fstat(fd[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.5.0接受额外的 options 对象来指定返回的数值是否应该是大整数 (bigint)。
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它会发出带有 ID DEP0013 的弃用警告。
v0.1.95新增于:v0.1.95

使用文件描述符调用带有 <fs.Stats> 的回调函数。

更多细节,请参考 POSIX fstat(2) 文档。

fs.fsync(fd, callback)

[历史]

版本变更
v18.0.0callback 参数传递无效回调现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再可选。不传递它将在运行时抛出 TypeError
v7.0.0callback 参数不再可选。不传递它将发出 ID 为 DEP0013 的弃用警告。
v0.1.96新增于:v0.1.96

请求将打开的文件描述符的所有数据刷新到存储设备。具体的实现取决于操作系统和设备。有关更多详细信息,请参阅 POSIX fsync(2) 文档。完成回调除了可能的异常之外,没有其他参数。

fs.ftruncate(fd[, len], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再可选。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再可选。不传递它会发出带有 ID DEP0013 的弃用警告。
v0.8.6添加于:v0.8.6

截断文件描述符。完成回调函数除了可能的异常之外,不会传入任何其他参数。

有关更多详细信息,请参阅 POSIX ftruncate(2) 文档。

如果文件描述符引用的文件大于 len 字节,则文件中只保留前 len 个字节。

例如,以下程序只保留文件的头四个字节:

js
import { open, close, ftruncate } from 'node:fs'

function closeFd(fd) {
  close(fd, err => {
    if (err) throw err
  })
}

open('temp.txt', 'r+', (err, fd) => {
  if (err) throw err

  try {
    ftruncate(fd, 4, err => {
      closeFd(fd)
      if (err) throw err
    })
  } catch (err) {
    closeFd(fd)
    if (err) throw err
  }
})

如果文件以前短于 len 字节,则会扩展它,并且扩展部分将填充空字节('\0'):

如果 len 为负数,则将使用 0

fs.futimes(fd, atime, mtime, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v4.1.0数值字符串、NaNInfinity 现在允许作为时间说明符。
v0.4.2新增于:v0.4.2

更改由提供的文件描述符引用的对象的 文件系统时间戳。参见 fs.utimes()

fs.glob(pattern[, options], callback)

[历史]

版本变更
v22.2.0添加对 withFileTypes 选项的支持。
v22.0.0v22.0.0 版本中添加

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

  • pattern <字符串> | <字符串数组>

  • options <对象>

    • cwd <字符串> 当前工作目录。默认值: process.cwd()
    • exclude <函数> 用于过滤文件/目录的函数。返回 true 表示排除该项,返回 false 表示包含该项。默认值: undefined
    • withFileTypes <布尔值> true 表示 glob 应将路径作为 Dirents 返回,false 则相反。默认值: false
  • callback <函数>

  • 检索与指定模式匹配的文件。

js
import { glob } from 'node:fs'

glob('**/*.js', (err, matches) => {
  if (err) throw err
  console.log(matches)
})
js
const { glob } = require('node:fs')

glob('**/*.js', (err, matches) => {
  if (err) throw err
  console.log(matches)
})

fs.lchmod(path, mode, callback)

[历史]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v16.0.0如果返回多个错误,则返回的错误可能是 AggregateError
v10.0.0callback 参数不再可选。不传递它将在运行时抛出 TypeError
v7.0.0callback 参数不再可选。不传递它将发出带有 ID DEP0013 的弃用警告。
v0.4.7自 v0.4.7 起已弃用

更改符号链接的权限。完成回调除了可能的异常之外,不接受任何参数。

此方法仅在 macOS 上实现。

有关更多详细信息,请参阅 POSIX lchmod(2) 文档。

fs.lchown(path, uid, gid, callback)

[历史]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.6.0此 API 不再弃用。
v10.0.0callback 参数不再可选。不传递它会在运行时抛出 TypeError
v7.0.0callback 参数不再可选。不传递它会发出带有 ID DEP0013 的弃用警告。
v0.4.7仅文档弃用。

设置符号链接的所有者。完成回调除了可能的异常之外没有其他参数。

有关更多详细信息,请参阅 POSIX lchown(2) 文档。

fs.lutimes(path, atime, mtime, callback)

[历史]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v14.5.0, v12.19.0新增于:v14.5.0, v12.19.0

以与 fs.utimes() 相同的方式更改文件的访问和修改时间,不同之处在于,如果路径引用符号链接,则不会取消引用该链接:而是更改符号链接本身的时间戳。

完成回调除了可能的异常之外,没有其他参数。

fs.link(existingPath, newPath, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.6.0existingPathnewPath 参数可以使用使用 file: 协议的 WHATWG URL 对象。目前支持仍然是实验性的
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.1.31添加于:v0.1.31

existingPath 创建一个到 newPath 的新链接。有关更多详细信息,请参阅 POSIX link(2) 文档。完成回调中除了可能的异常之外,没有给出其他参数。

fs.lstat(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.5.0接受额外的 options 对象来指定返回的数值是否应该为 BigInt。
v10.0.0callback 参数不再可选。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再可选。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.1.30添加于:v0.1.30

检索由路径引用的符号链接的 <fs.Stats>。回调获得两个参数 (err, stats),其中 stats 是一个 <fs.Stats> 对象。lstat()stat() 相同,但如果 path 是符号链接,则会对链接本身进行 stat 操作,而不是它所引用的文件。

有关更多详细信息,请参阅 POSIX lstat(2) 文档。

fs.mkdir(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v13.11.0, v12.17.0recursive 模式下,回调现在接收第一个创建的路径作为参数。
v10.12.0第二个参数现在可以是一个包含 recursivemode 属性的 options 对象。
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出一个 TypeError
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出一个带有 ID DEP0013 的弃用警告。
v0.1.8新增于:v0.1.8

异步创建目录。

回调函数会返回一个可能的异常,如果 recursivetrue,则返回第一个创建的目录路径 (err[, path])。当 recursivetrue 但没有创建目录时(例如,如果目录已存在),path 仍然可能为 undefined

可选的 options 参数可以是一个整数,指定 mode(权限和粘性位),或者是一个对象,包含 mode 属性和 recursive 属性,指示是否应创建父目录。当 path 是一个已存在的目录时调用 fs.mkdir() 只会在 recursivefalse 时导致错误。如果 recursivefalse 且目录存在,则会发生 EEXIST 错误。

js
import { mkdir } from 'node:fs'

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

在 Windows 系统上,即使使用递归,在根目录上使用 fs.mkdir() 也会导致错误:

js
import { mkdir } from 'node:fs'

mkdir('/', { recursive: true }, err => {
  // => [Error: EPERM: operation not permitted, mkdir 'C:\']
})

有关更多详细信息,请参阅 POSIX mkdir(2) 文档。

fs.mkdtemp(prefix[, options], callback)

[历史]

版本变更
v20.6.0, v18.19.0prefix 参数现在接受缓冲区和 URL。
v18.0.0将无效回调传递给 callback 参数现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v16.5.0, v14.18.0prefix 参数现在接受空字符串。
v10.0.0callback 参数不再是可选的。不传递它将在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它将发出带有 ID DEP0013 的弃用警告。
v6.2.1callback 参数现在是可选的。
v5.10.0新增于:v5.10.0

创建唯一的临时目录。

生成六个随机字符,附加到必需的 prefix 后面以创建唯一的临时目录。由于平台不一致,请避免在 prefix 中使用尾随的 X 字符。某些平台(特别是 BSD)可能会返回超过六个随机字符,并将 prefix 中的尾随 X 字符替换为随机字符。

创建的目录路径作为字符串传递给回调的第二个参数。

可选的 options 参数可以是一个指定编码的字符串,或者是一个带有 encoding 属性的对象,用于指定要使用的字符编码。

js
import { mkdtemp } from 'node:fs'
import { join } from 'node:path'
import { tmpdir } from 'node:os'

mkdtemp(join(tmpdir(), 'foo-'), (err, directory) => {
  if (err) throw err
  console.log(directory)
  // 打印:/tmp/foo-itXde2 或 C:\Users\...\AppData\Local\Temp\foo-itXde2
})

fs.mkdtemp() 方法会将六个随机选择的字符直接附加到 prefix 字符串。例如,给定一个目录 /tmp,如果目的是在 /tmp 内部 创建一个临时目录,则 prefix 必须以平台特定的路径分隔符结尾 (require('node:path').sep)。

js
import { tmpdir } from 'node:os'
import { mkdtemp } from 'node:fs'

// 新建临时目录的父目录
const tmpDir = tmpdir()

// 此方法*不正确*:
mkdtemp(tmpDir, (err, directory) => {
  if (err) throw err
  console.log(directory)
  // 将打印类似于 `/tmpabc123` 的内容。
  // 新建的临时目录是在文件系统根目录下创建的,
  // 而不是在 /tmp 目录*内部*。
})

// 此方法*正确*:
import { sep } from 'node:path'
mkdtemp(`${tmpDir}${sep}`, (err, directory) => {
  if (err) throw err
  console.log(directory)
  // 将打印类似于 `/tmp/abc123` 的内容。
  // 新建的临时目录是在 /tmp 目录*内部*创建的。
})

fs.open(path[, flags[, mode]], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v11.1.0flags 参数现在是可选的,默认为 'r'
v9.9.0现在支持 asas+ 标志。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v0.0.2新增于:v0.0.2

异步文件打开。有关更多详细信息,请参见 POSIX open(2) 文档。

mode 设置文件模式(权限和粘滞位),但仅当创建文件时才设置。在 Windows 上,只能操作写入权限;参见 fs.chmod()

回调函数获取两个参数 (err, fd)

某些字符(< > : " / \ | ? *)在 Windows 下是保留字符,如 命名文件、路径和命名空间 中所述。在 NTFS 下,如果文件名包含冒号,Node.js 将打开一个文件系统流,如 此 MSDN 页面 所述。

基于 fs.open() 的函数也表现出这种行为:fs.writeFile()fs.readFile() 等。

fs.openAsBlob(path[, options])

新增于:v19.8.0

[稳定性:1 - 实验性]

稳定性:1 稳定性:1 - 实验性

返回一个 <Blob>,其数据由给定文件支持。

在创建 <Blob> 后,不得修改文件。任何修改都将导致读取 <Blob> 数据失败,并出现 DOMException 错误。在创建 Blob 时以及每次读取之前,都会对文件执行同步状态操作,以检测文件数据是否已在磁盘上修改。

js
import { openAsBlob } from 'node:fs'

const blob = await openAsBlob('the.file.txt')
const ab = await blob.arrayBuffer()
blob.stream()
js
const { openAsBlob } = require('node:fs')

;(async () => {
  const blob = await openAsBlob('the.file.txt')
  const ab = await blob.arrayBuffer()
  blob.stream()
})()

fs.opendir(path[, options], callback)

[历史]

版本变更
v20.1.0, v18.17.0添加了 recursive 选项。
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v13.1.0, v12.16.0引入了 bufferSize 选项。
v12.12.0v12.12.0 版本中添加

异步打开目录。有关更多详细信息,请参阅 POSIX opendir(3) 文档。

创建一个 <fs.Dir>,其中包含用于从目录读取和清理目录的所有其他函数。

encoding 选项在打开目录和后续读取操作时设置 path 的编码。

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

[历史记录]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.10.0buffer 参数现在可以是任何 TypedArrayDataView
v7.4.0buffer 参数现在可以是 Uint8Array
v6.0.0length 参数现在可以为 0
v0.0.2新增于:v0.0.2

fd 指定的文件中读取数据。

回调函数接受三个参数 (err, bytesRead, buffer)

如果文件没有被并发修改,当读取的字节数为零时,则达到文件结尾。

如果此方法作为其 util.promisify() 版本调用,它将返回一个包含 bytesReadbuffer 属性的 Object 的 Promise。

fs.read() 方法从文件描述符 (fd) 指定的文件中读取数据。length 参数指示 Node.js 将尝试从内核读取的最大字节数。但是,由于各种原因,实际读取的字节数 (bytesRead) 可能小于指定的 length

例如:

  • 如果文件短于指定的 length,则 bytesRead 将设置为实际读取的字节数。
  • 如果文件在缓冲区填充之前遇到 EOF(文件结尾),Node.js 将读取所有可用字节直到遇到 EOF,并且回调中的 bytesRead 参数将指示实际读取的字节数,这可能小于指定的 length
  • 如果文件位于速度慢的网络 filesystem 上或在读取过程中遇到任何其他问题,则 bytesRead 可能小于指定的 length

因此,使用 fs.read() 时,务必检查 bytesRead 值以确定实际从文件中读取了多少字节。根据您的应用程序逻辑,您可能需要处理 bytesRead 小于指定 length 的情况,例如,如果您需要最小数量的字节,则可以通过循环包装读取调用来处理。

此行为类似于 POSIX preadv2 函数。

fs.read(fd[, options], callback)

[历史]

版本变更
v13.11.0, v12.17.0可传入 options 对象,使 buffer、offset、length 和 position 可选。
v13.11.0, v12.17.0新增于:v13.11.0, v12.17.0

类似于 fs.read() 函数,此版本接受一个可选的 options 对象。如果未指定 options 对象,则将使用上述默认值。

fs.read(fd, buffer[, options], callback)

新增于:v18.2.0, v16.17.0

类似于 fs.read() 函数,此版本接受可选的 options 对象。如果未指定 options 对象,则将使用上述默认值。

fs.readdir(path[, options], callback)

[历史]

版本变更
v20.1.0, v18.17.0新增 recursive 选项。
v18.0.0callback 参数传递无效回调现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.10.0新增选项 withFileTypes
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v6.0.0新增 options 参数。
v0.1.8v0.1.8 版本中添加

读取目录的内容。回调函数获取两个参数 (err, files),其中 files 是目录中文件名称的数组,不包括 '.''..'

有关更多详细信息,请参阅 POSIX readdir(3) 文档。

可选的 options 参数可以是一个指定编码的字符串,或者是一个具有 encoding 属性的对象,该属性指定用于传递给回调函数的文件名的字符编码。如果将 encoding 设置为 'buffer',则返回的文件名将作为 <Buffer> 对象传递。

如果将 options.withFileTypes 设置为 true,则 files 数组将包含 <fs.Dirent> 对象。

fs.readFile(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v16.0.0如果返回多个错误,则返回的错误可能是 AggregateError
v15.2.0, v14.17.0options 参数可以包含一个 AbortSignal 来中止正在进行的 readFile 请求。
v10.0.0callback 参数不再是可选的。不传递它将在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它将发出 ID 为 DEP0013 的弃用警告。
v5.1.0成功的情况下,callback 将始终使用 null 作为 error 参数调用。
v5.0.0path 参数现在可以是文件描述符。
v0.1.29新增于:v0.1.29

异步读取文件的全部内容。

js
import { readFile } from 'node:fs'

readFile('/etc/passwd', (err, data) => {
  if (err) throw err
  console.log(data)
})

回调函数传递两个参数 (err, data),其中 data 是文件的内容。

如果没有指定编码,则返回原始缓冲区。

如果 options 是一个字符串,则它指定编码:

js
import { readFile } from 'node:fs'

readFile('/etc/passwd', 'utf8', callback)

当路径是一个目录时,fs.readFile()fs.readFileSync() 的行为是特定于平台的。在 macOS、Linux 和 Windows 上,将返回错误。在 FreeBSD 上,将返回目录内容的表示。

js
import { readFile } from 'node:fs'

// macOS、Linux 和 Windows
readFile('<directory>', (err, data) => {
  // => [Error: EISDIR: illegal operation on a directory, read <directory>]
})

//  FreeBSD
readFile('<directory>', (err, data) => {
  // => null, <data>
})

可以使用 AbortSignal 中止正在进行的请求。如果请求被中止,则回调函数将使用 AbortError 调用:

js
import { readFile } from 'node:fs'

const controller = new AbortController()
const signal = controller.signal
readFile(fileInfo[0].name, { signal }, (err, buf) => {
  // ...
})
// 当您想要中止请求时
controller.abort()

fs.readFile() 函数缓冲整个文件。为了最大限度地降低内存成本,如果可能,最好通过 fs.createReadStream() 进行流式传输。

中止正在进行的请求不会中止单个操作系统请求,而是中止 fs.readFile 执行的内部缓冲。

文件描述符

性能考虑

fs.readFile() 方法异步地将文件内容一次读取一个块到内存中,允许事件循环在每个块之间轮换。这使得读取操作对可能正在使用底层 libuv 线程池的其他活动的影响较小,但意味着将完整文件读取到内存中需要更长时间。

额外的读取开销在不同的系统上差异很大,并且取决于正在读取的文件类型。如果文件类型不是常规文件(例如管道),而 Node.js 无法确定实际的文件大小,则每次读取操作将加载 64 KiB 的数据。对于常规文件,每次读取将处理 512 KiB 的数据。

对于需要尽可能快地读取文件内容的应用程序,最好直接使用 fs.read(),并让应用程序代码自己管理读取文件的完整内容。

Node.js GitHub issue #25741 提供了更多信息以及对不同 Node.js 版本中 fs.readFile() 在多个文件大小下的性能的详细分析。

fs.readlink(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再可选。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再可选。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.1.31新增于:v0.1.31

读取 path 所指向的符号链接的内容。回调函数获取两个参数 (err, linkString)

有关更多详细信息,请参阅 POSIX readlink(2) 文档。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定用于传递给回调函数的链接路径的字符编码。如果 encoding 设置为 'buffer',则返回的链接路径将作为 <Buffer> 对象传递。

fs.readv(fd, buffers[, position], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v13.13.0, v12.17.0新增于:v13.13.0, v12.17.0

从由 fd 指定的文件中读取数据,并使用 readv() 写入 ArrayBufferView 数组。

position 是从文件开头开始读取数据的偏移量。如果 typeof position !== 'number',则将从当前位置读取数据。

回调函数将接收三个参数:errbytesReadbuffersbytesRead 是从文件中读取的字节数。

如果此方法作为其 util.promisify() 版本调用,则它返回一个包含 bytesReadbuffers 属性的 Object 的 Promise。

fs.realpath(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v8.0.0添加了管道/套接字解析支持。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v6.4.0realpath 的调用现在再次适用于 Windows 上的各种极端情况。
v6.0.0cache 参数已移除。
v0.1.31添加于:v0.1.31

异步计算规范路径名,方法是解析 ., .. 和符号链接。

规范路径名不一定是唯一的。硬链接和绑定挂载可以通过许多路径名公开文件系统实体。

此函数的行为类似于 realpath(3),但有一些例外:

callback 获取两个参数 (err, resolvedPath)。可以使用 process.cwd 解析相对路径。

仅支持可以转换为 UTF8 字符串的路径。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定用于传递给回调的路径的字符编码。如果将 encoding 设置为 'buffer',则返回的路径将作为 <Buffer> 对象传递。

如果 path 解析为套接字或管道,则函数将返回该对象的系统相关名称。

不存在的路径会导致 ENOENT 错误。error.path 是绝对文件路径。

fs.realpath.native(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v9.2.0新增于:v9.2.0

异步 realpath(3)

callback 获取两个参数 (err, resolvedPath)

仅支持可以转换为 UTF8 字符串的路径。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定用于传递给回调的路径的字符编码。如果将 encoding 设置为 'buffer',则返回的路径将作为 <Buffer> 对象传递。

在 Linux 上,当 Node.js 链接到 musl libc 时,必须在 /proc 上挂载 procfs 文件系统才能使此函数工作。Glibc 没有此限制。

fs.rename(oldPath, newPath, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它将在运行时抛出 TypeError
v7.6.0oldPathnewPath 参数可以使用 file: 协议的 WHATWG URL 对象。目前支持仍在 实验 阶段。
v7.0.0callback 参数不再是可选的。不传递它将发出一个带有 ID DEP0013 的弃用警告。
v0.0.2v0.0.2 版本中添加

异步地将 oldPath 处的文件重命名为 newPath 指定的文件名。如果 newPath 已存在,它将被覆盖。如果 newPath 处存在目录,则会引发错误。完成回调除了可能的异常之外,不会给出其他参数。

另请参见:rename(2)

js
import { rename } from 'node:fs'

rename('oldFile.txt', 'newFile.txt', err => {
  if (err) throw err
  console.log('Rename complete!')
})

fs.rmdir(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v16.0.0path 为文件的路径上使用 fs.rmdir(path, { recursive: true }) 现在不再允许,并在 Windows 上导致 ENOENT 错误,在 POSIX 上导致 ENOTDIR 错误。
v16.0.0path 不存在的路径上使用 fs.rmdir(path, { recursive: true }) 现在不再允许,并导致 ENOENT 错误。
v16.0.0recursive 选项已弃用,使用它会触发弃用警告。
v14.14.0recursive 选项已弃用,请改用 fs.rm
v13.3.0, v12.16.0maxBusyTries 选项已重命名为 maxRetries,其默认值为 0。emfileWait 选项已被移除,EMFILE 错误使用与其他错误相同的重试逻辑。现在支持 retryDelay 选项。现在重试 ENFILE 错误。
v12.10.0现在支持 recursivemaxBusyTriesemfileWait 选项。
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.0.2添加于:v0.0.2
  • path <字符串> | <Buffer> | <URL>

  • options <对象>

    • maxRetries <整数> 如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 会使用每次尝试都线性增加 retryDelay 毫秒的回退等待时间来重试操作。此选项表示重试次数。如果 recursive 选项不是 true,则忽略此选项。默认值:0
    • recursive <布尔值> 如果为 true,则执行递归目录删除。在递归模式下,操作会在失败时重试。默认值:false已弃用。
    • retryDelay <整数> 重试之间等待的时间量(毫秒)。如果 recursive 选项不是 true,则忽略此选项。默认值:100
  • callback <函数>

异步 rmdir(2)。完成回调除了可能的异常外,没有其他参数。

在文件(而不是目录)上使用 fs.rmdir() 会导致 Windows 上出现 ENOENT 错误,在 POSIX 上出现 ENOTDIR 错误。

要获得类似于 rm -rf Unix 命令的行为,请使用 fs.rm() 并设置选项 { recursive: true, force: true }

fs.rm(path[, options], callback)

[历史]

版本变更
v17.3.0, v16.14.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v14.14.0v14.14.0 中添加
  • path <字符串> | <Buffer> | <URL>

  • options <对象>

    • force <布尔值> 当值为 true 时,如果 path 不存在,则忽略异常。默认值: false
    • maxRetries <整数> 如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 将重试该操作,每次重试都会线性增加 retryDelay 毫秒的等待时间。此选项表示重试次数。如果 recursive 选项不是 true,则忽略此选项。默认值: 0
    • recursive <布尔值> 如果为 true,则执行递归删除。在递归模式下,操作失败时会重试。默认值: false
    • retryDelay <整数> 重试之间等待的时间(毫秒)。如果 recursive 选项不是 true,则忽略此选项。默认值: 100
  • callback <函数>

异步删除文件和目录(基于标准 POSIX rm 实用程序)。完成回调函数除了可能的异常之外,没有其他参数。

fs.stat(path[, options], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.5.0接受一个额外的 options 对象来指定返回的数值是否应该是大整数。
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出一个 TypeError
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出一个带有 ID DEP0013 的弃用警告。
v0.0.2添加于:v0.0.2

异步 stat(2)。回调函数接收两个参数 (err, stats),其中 stats 是一个 <fs.Stats> 对象。

如果发生错误,err.code 将是 常见系统错误 之一。

fs.stat() 遵循符号链接。使用 fs.lstat() 来查看链接本身。

不建议使用 fs.stat() 在调用 fs.open()fs.readFile()fs.writeFile() 之前检查文件是否存在。相反,用户代码应该直接打开/读取/写入文件,并在文件不可用时处理引发的错误。

要检查文件是否存在而不随后操作它,建议使用 fs.access()

例如,给定以下目录结构:

text
- txtDir
-- file.txt
- app.js

下面的程序将检查给定路径的统计信息:

js
import { stat } from 'node:fs'

const pathsToCheck = ['./txtDir', './txtDir/file.txt']

for (let i = 0; i < pathsToCheck.length; i++) {
  stat(pathsToCheck[i], (err, stats) => {
    console.log(stats.isDirectory())
    console.log(stats)
  })
}

生成的输出将类似于:

bash
true
Stats {
  dev: 16777220,
  mode: 16877,
  nlink: 3,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14214262,
  size: 96,
  blocks: 0,
  atimeMs: 1561174653071.963,
  mtimeMs: 1561174614583.3518,
  ctimeMs: 1561174626623.5366,
  birthtimeMs: 1561174126937.2893,
  atime: 2019-06-22T03:37:33.072Z,
  mtime: 2019-06-22T03:36:54.583Z,
  ctime: 2019-06-22T03:37:06.624Z,
  birthtime: 2019-06-22T03:28:46.937Z
}
false
Stats {
  dev: 16777220,
  mode: 33188,
  nlink: 1,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 14214074,
  size: 8,
  blocks: 8,
  atimeMs: 1561174616618.8555,
  mtimeMs: 1561174614584,
  ctimeMs: 1561174614583.8145,
  birthtimeMs: 1561174007710.7478,
  atime: 2019-06-22T03:36:56.619Z,
  mtime: 2019-06-22T03:36:54.584Z,
  ctime: 2019-06-22T03:36:54.584Z,
  birthtime: 2019-06-22T03:26:47.711Z
}

fs.statfs(path[, options], callback)

新增于:v19.6.0, v18.15.0

异步 statfs(2)。返回包含 path 的已挂载文件系统的信息。回调函数接收两个参数 (err, stats),其中 stats 是一个 <fs.StatFs> 对象。

如果发生错误,则 err.code 将是 常见系统错误 之一。

fs.symlink(target, path[, type], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v12.0.0如果 type 参数未定义,Node 将自动检测 target 类型并自动选择 dirfile
v7.6.0targetpath 参数可以使用 file: 协议的 WHATWG URL 对象。目前支持仍在 实验 阶段。
v0.1.31在 v0.1.31 中添加

创建名为 path 的指向 target 的链接。完成回调中除了可能的异常之外,没有其他参数。

有关更多详细信息,请参阅 POSIX symlink(2) 文档。

type 参数仅在 Windows 上可用,在其他平台上被忽略。它可以设置为 'dir''file''junction'。如果 type 参数为 null,Node.js 将自动检测 target 类型并使用 'file''dir'。如果 target 不存在,将使用 'file'。Windows 链接点要求目标路径为绝对路径。使用 'junction' 时,target 参数将自动规范化为绝对路径。NTFS 卷上的链接点只能指向目录。

相对目标相对于链接的父目录。

js
import { symlink } from 'node:fs'

symlink('./mew', './mewtwo', callback)

上面的示例创建了一个名为 mewtwo 的符号链接,它指向同一目录中的 mew

bash
$ tree .
.
├── mew
└── mewtwo -> ./mew

fs.truncate(path[, len], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v16.0.0如果返回多个错误,则返回的错误可能是 AggregateError
v10.0.0callback 参数不再是可选的。不传递它将在运行时抛出 TypeError
v7.0.0callback 参数不再是可选的。不传递它将发出带有 ID DEP0013 的弃用警告。
v0.8.6新增于:v0.8.6

截断文件。除了可能的异常之外,不会向完成回调提供其他参数。文件描述符也可以作为第一个参数传递。在这种情况下,将调用 fs.ftruncate()

js
import { truncate } from 'node:fs'
// 假设 'path/file.txt' 是一个普通文件。
truncate('path/file.txt', err => {
  if (err) throw err
  console.log('path/file.txt 已被截断')
})
js
const { truncate } = require('node:fs')
// 假设 'path/file.txt' 是一个普通文件。
truncate('path/file.txt', err => {
  if (err) throw err
  console.log('path/file.txt 已被截断')
})

传递文件描述符已被弃用,将来可能会导致抛出错误。

有关更多详细信息,请参阅 POSIX truncate(2) 文档。

fs.unlink(path, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.0.2添加于:v0.0.2

异步删除文件或符号链接。完成回调中除了可能的异常外,没有其他参数。

js
import { unlink } from 'node:fs'
// 假设 'path/file.txt' 是一个普通文件。
unlink('path/file.txt', err => {
  if (err) throw err
  console.log('path/file.txt 已删除')
})

fs.unlink() 无法作用于目录,无论该目录是否为空。要删除目录,请使用 fs.rmdir()

有关更多详细信息,请参阅 POSIX unlink(2) 文档。

fs.unwatchFile(filename[, listener])

新增于:v0.1.31

停止监视 filename 的更改。如果指定了 listener,则仅移除该特定监听器。否则,将移除所有监听器,有效地停止监视 filename

使用未被监视的文件名调用 fs.unwatchFile() 是一个空操作,而不是错误。

使用 fs.watch()fs.watchFile()fs.unwatchFile() 更有效。应尽可能使用 fs.watch() 代替 fs.watchFile()fs.unwatchFile()

fs.utimes(path, atime, mtime, callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v8.0.0NaNInfinity-Infinity 不再是有效的時間說明符。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0callback 参数不再是可选的。不传递它将发出 ID 为 DEP0013 的弃用警告。
v4.1.0数字字符串、NaNInfinity 现在允许作为时间说明符。
v0.4.2新增于:v0.4.2

更改 path 引用的对象的 文件系统时间戳。

atimemtime 参数遵循以下规则:

  • 值可以是表示以秒为单位的 Unix 时间戳的数字、Date 对象或类似 '123456789.0' 的数字字符串。
  • 如果值不能转换为数字,或者为 NaNInfinity-Infinity,则会抛出 Error

fs.watch(filename[, options][, listener])

[历史]

版本变更
v19.1.0为 Linux、AIX 和 IBMi 添加了递归支持。
v15.9.0, v14.17.0添加了使用 AbortSignal 关闭监视器的支持。
v7.6.0filename 参数可以使用 file: 协议使用 WHATWG URL 对象。
v7.0.0传递的 options 对象将永远不会被修改。
v0.5.10添加于:v0.5.10

监视 filename 上的更改,其中 filename 是文件或目录。

第二个参数是可选的。如果 options 提供为字符串,则它指定 encoding。否则,应将 options 作为对象传递。

侦听器回调获取两个参数 (eventType, filename)eventType'rename''change'filename 是触发事件的文件名。

在大多数平台上,每当目录中出现或消失文件名时,都会发出 'rename'

侦听器回调附加到由 <fs.FSWatcher> 发出的 'change' 事件,但它与 eventType'change' 值不同。

如果传递了 signal,则中止相应的 AbortController 将关闭返回的 <fs.FSWatcher>

注意事项

fs.watch API 并非在所有平台上都完全一致,并且在某些情况下不可用。

在 Windows 系统上,如果被监视的目录被移动或重命名,则不会发出任何事件。当被监视的目录被删除时,会报告 EPERM 错误。

可用性

此功能取决于底层操作系统提供一种通知文件系统更改的方法。

  • 在 Linux 系统上,这使用 inotify(7)
  • 在 BSD 系统上,这使用 kqueue(2)
  • 在 macOS 系统上,这使用 kqueue(2) 用于文件,以及 FSEvents 用于目录。
  • 在 SunOS 系统(包括 Solaris 和 SmartOS)上,这使用 event ports
  • 在 Windows 系统上,此功能取决于 ReadDirectoryChangesW
  • 在 AIX 系统上,此功能取决于 AHAFS,必须启用此功能。
  • 在 IBM i 系统上,不支持此功能。

如果由于某种原因底层功能不可用,则 fs.watch() 将无法运行,并可能抛出异常。例如,在网络文件系统 (NFS、SMB 等) 或使用虚拟化软件(如 Vagrant 或 Docker)时的主机文件系统上,监视文件或目录可能不可靠,在某些情况下甚至不可能。

仍然可以使用 fs.watchFile(),它使用状态轮询,但是这种方法较慢且可靠性较低。

inode 节点

在 Linux 和 macOS 系统上,fs.watch() 将路径解析为一个 inode 节点 并监视该 inode 节点。如果被监视的路径被删除并重新创建,则会分配一个新的 inode 节点。监视将为删除事件发出一个事件,但将继续监视 原始 inode 节点。不会为新的 inode 节点发出事件。这是预期行为。

AIX 文件在文件生命周期内保留相同的 inode 节点。在 AIX 上保存并关闭被监视的文件将导致两次通知(一次用于添加新内容,一次用于截断)。

文件名参数

回调函数中仅支持在 Linux、macOS、Windows 和 AIX 上提供 filename 参数。即使在受支持的平台上,也不能保证始终提供 filename。因此,不要假设回调函数中始终提供 filename 参数,如果没有,请使用一些后备逻辑。

js
import { watch } from 'node:fs'
watch('somedir', (eventType, filename) => {
  console.log(`事件类型是: ${eventType}`)
  if (filename) {
    console.log(`文件名已提供: ${filename}`)
  } else {
    console.log('文件名未提供')
  }
})

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

[历史记录]

版本变更
v10.5.0现在支持 bigint 选项。
v7.6.0filename 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.31v0.1.31 版本中添加

监视 filename 的更改。每次访问文件时,都会调用回调函数 listener

可以省略 options 参数。如果提供,则应为一个对象。options 对象可以包含一个名为 persistent 的布尔值,指示进程是否应该在正在监视文件时继续运行。options 对象可以指定一个 interval 属性,指示应以毫秒为单位轮询目标的频率。

listener 获取两个参数:当前状态对象和先前状态对象:

js
import { watchFile } from 'node:fs'

watchFile('message.text', (curr, prev) => {
  console.log(`当前 mtime 为:${curr.mtime}`)
  console.log(`之前的 mtime 为:${prev.mtime}`)
})

这些状态对象是 fs.Stat 的实例。如果 bigint 选项为 true,则这些对象中的数值将指定为 BigInt

要收到文件修改的通知,而不仅仅是访问通知,则需要比较 curr.mtimeMsprev.mtimeMs

fs.watchFile 操作导致 ENOENT 错误时,它将调用监听器一次,所有字段都为零(或对于日期,则为 Unix 纪元)。如果稍后创建文件,则将再次调用监听器,并使用最新的状态对象。这是自 v0.10 版本以来的功能变化。

使用 fs.watch()fs.watchFilefs.unwatchFile 更有效。尽可能使用 fs.watch 代替 fs.watchFilefs.unwatchFile

fs.watchFile() 监视的文件消失又重新出现时,第二个回调事件(文件重新出现)中的 previous 内容将与第一个回调事件(文件消失)中的 previous 内容相同。

这种情况发生在:

  • 文件被删除,然后恢复
  • 文件被重命名,然后再次重命名回其原始名称

fs.write(fd, buffer, offset[, length[, position]], callback)

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v14.0.0buffer 参数不再会将不支持的输入强制转换为字符串。
v10.10.0buffer 参数现在可以是任何 TypedArrayDataView
v10.0.0callback 参数不再是可选的。不传递它会在运行时抛出 TypeError
v7.4.0buffer 参数现在可以是 Uint8Array
v7.2.0offsetlength 参数现在是可选的。
v7.0.0callback 参数不再是可选的。不传递它会发出 ID 为 DEP0013 的弃用警告。
v0.0.2添加于:v0.0.2

buffer 写入由 fd 指定的文件。

offset 确定要写入的缓冲区部分,length 是一个整数,指定要写入的字节数。

position 指的是从文件开头开始写入此数据的偏移量。如果 typeof position !== 'number',则数据将写入当前位置。参见 pwrite(2)

回调将获得三个参数 (err, bytesWritten, buffer),其中 bytesWritten 指定从 buffer 写入的 字节 数。

如果此方法作为其 util.promisify() 版本调用,它将返回一个包含 bytesWrittenbuffer 属性的 Object 的 Promise。

在同一个文件上多次调用 fs.write() 而不等待回调是不安全的。对于这种情况,建议使用 fs.createWriteStream()

在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略 position 参数,并将数据始终追加到文件的末尾。

fs.write(fd, buffer[, options], callback)

新增于: v18.3.0, v16.17.0

buffer 写入由 fd 指定的文件。

类似于上面的 fs.write 函数,此版本接受一个可选的 options 对象。如果没有指定 options 对象,它将使用上述值作为默认值。

fs.write(fd, string[, position[, encoding]], callback)

[历史]

版本变更
v19.0.0不再支持将具有自身 toString 函数的对象传递给 string 参数。
v17.8.0将具有自身 toString 函数的对象传递给 string 参数已弃用。
v14.12.0string 参数将使用显式 toString 函数将对象序列化为字符串。
v14.0.0string 参数不再强制将不支持的输入转换为字符串。
v10.0.0callback 参数不再是可选的。不传递它将在运行时抛出 TypeError
v7.2.0position 参数现在是可选的。
v7.0.0callback 参数不再是可选的。不传递它将发出带有 ID DEP0013 的弃用警告。
v0.11.5新增于:v0.11.5

string 写入由 fd 指定的文件。如果 string 不是字符串,则抛出异常。

position 指的是从文件开头开始写入此数据的偏移量。如果 typeof position !== 'number',则数据将写入当前位置。参见 pwrite(2)

encoding 是预期的字符串编码。

回调函数将接收参数 (err, written, string),其中 written 指定传递的字符串需要写入多少个字节。写入的字节数不一定与写入的字符串字符数相同。参见 Buffer.byteLength

在没有等待回调的情况下,多次对同一文件使用 fs.write() 是不安全的。对于这种情况,建议使用 fs.createWriteStream()

在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略 position 参数,并始终将数据追加到文件的末尾。

在 Windows 上,如果文件描述符连接到控制台(例如 fd == 1stdout),则包含非 ASCII 字符的字符串默认情况下将无法正确渲染,无论使用何种编码。可以通过使用 chcp 65001 命令更改活动代码页来配置控制台以正确呈现 UTF-8。有关更多详细信息,请参阅 chcp 文档。

fs.writeFile(file, data[, options], callback)

[历史]

版本变更
v21.0.0, v20.10.0现在支持 flush 选项。
v19.0.0不再支持将具有自身 toString 函数的对象传递给 string 参数。
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v17.8.0将具有自身 toString 函数的对象传递给 string 参数已弃用。
v16.0.0如果返回多个错误,则返回的错误可能是 AggregateError
v15.2.0, v14.17.0options 参数可以包含 AbortSignal 来中止正在进行的 writeFile 请求。
v14.12.0data 参数将使用显式 toString 函数序列化对象。
v14.0.0data 参数不再强制将不支持的输入转换为字符串。
v10.10.0data 参数现在可以是任何 TypedArrayDataView
v10.0.0callback 参数不再是可选的。不传递它将在运行时抛出 TypeError
v7.4.0data 参数现在可以是 Uint8Array
v7.0.0callback 参数不再是可选的。不传递它将发出具有 ID DEP0013 的弃用警告。
v5.0.0file 参数现在可以是文件描述符。
v0.1.29添加于:v0.1.29

file 是文件名时,异步地将数据写入文件,如果文件已存在则替换该文件。data 可以是字符串或缓冲区。

file 是文件描述符时,其行为类似于直接调用 fs.write()(建议这样做)。请参阅下面关于使用文件描述符的说明。

如果 data 是缓冲区,则忽略 encoding 选项。

mode 选项仅影响新创建的文件。有关更多详细信息,请参阅 fs.open()

js
import { writeFile } from 'node:fs'
import { Buffer } from 'node:buffer'

const data = new Uint8Array(Buffer.from('Hello Node.js'))
writeFile('message.txt', data, err => {
  if (err) throw err
  console.log('The file has been saved!')
})

如果 options 是字符串,则它指定编码:

js
import { writeFile } from 'node:fs'

writeFile('message.txt', 'Hello Node.js', 'utf8', callback)

在没有等待回调的情况下,对同一文件多次使用 fs.writeFile() 是不安全的。对于这种情况,建议使用 fs.createWriteStream()

fs.readFile 类似 - fs.writeFile 是一种便捷方法,它在内部执行多个 write 调用以写入传递给它的缓冲区。对于性能敏感的代码,请考虑使用 fs.createWriteStream()

可以使用 <AbortSignal> 来取消 fs.writeFile()。取消是“尽力而为”的,一些数据可能会仍然被写入。

js
import { writeFile } from 'node:fs'
import { Buffer } from 'node:buffer'

const controller = new AbortController()
const { signal } = controller
const data = new Uint8Array(Buffer.from('Hello Node.js'))
writeFile('message.txt', data, { signal }, err => {
  // 当请求被中止时 - 回调函数将被调用并带有 AbortError
})
// 当请求应该被中止时
controller.abort()

中止正在进行的请求不会中止单个操作系统请求,而是中止 fs.writeFile 执行的内部缓冲。

使用文件描述符与 fs.writeFile()

file 是一个文件描述符时,其行为几乎与直接调用 fs.write() 相同,例如:

js
import { write } from 'node:fs'
import { Buffer } from 'node:buffer'

write(fd, Buffer.from(data, options.encoding), callback)

与直接调用 fs.write() 的区别在于,在某些异常情况下,fs.write() 可能会只写入缓冲区的一部分,需要重试才能写入剩余数据,而 fs.writeFile() 会一直重试直到所有数据写入完毕(或发生错误)。

这其中的含义是造成混淆的常见原因。在文件描述符的情况下,文件不会被替换!数据不一定写入文件的开头,并且文件原来的数据可能保留在新写入数据之前和/或之后。

例如,如果连续两次调用 fs.writeFile(),第一次写入字符串 'Hello',然后写入字符串 ', World',则文件将包含 'Hello, World',并且可能包含一些文件原来的数据(取决于原始文件的大小和文件描述符的位置)。如果使用文件名而不是描述符,则保证文件只包含 ', World'

fs.writev(fd, buffers[, position], callback)

[历史]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v12.9.0新增于:v12.9.0

使用 writev()ArrayBufferView 数组写入由 fd 指定的文件。

position 是从文件开头开始写入数据的偏移量。如果 typeof position !== 'number',则数据将写入当前位置。

回调函数将获得三个参数:errbytesWrittenbuffersbytesWritten 是从 buffers 中写入的字节数。

如果此方法被 util.promisify() 化,则它会返回一个包含 bytesWrittenbuffers 属性的 Object 的 Promise。

在没有等待回调的情况下,多次对同一文件使用 fs.writev() 是不安全的。对于这种情况,请使用 fs.createWriteStream()

在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略 position 参数,并始终将数据追加到文件的末尾。

同步 API

同步 API 同步执行所有操作,阻塞事件循环直至操作完成或失败。

fs.accessSync(path[, mode])

[历史]

版本变更
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.11.15v0.11.15 版本中添加

同步测试用户对 path 指定的文件或目录的权限。mode 参数是一个可选整数,指定要执行的可访问性检查。mode 应为 fs.constants.F_OK 值,或由 fs.constants.R_OKfs.constants.W_OKfs.constants.X_OK 的按位或运算组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK)。查看 文件访问常量 以了解 mode 的可能值。

如果任何可访问性检查失败,则会抛出 Error。否则,该方法将返回 undefined

js
import { accessSync, constants } from 'node:fs'

try {
  accessSync('etc/passwd', constants.R_OK | constants.W_OK)
  console.log('可读/写')
} catch (err) {
  console.error('无访问权限!')
}

fs.appendFileSync(path, data[, options])

[历史]

版本变更
v21.1.0, v20.10.0现在支持 flush 选项。
v7.0.0传递的 options 对象将永远不会被修改。
v5.0.0file 参数现在可以是文件描述符。
v0.6.7添加于:v0.6.7

同步地将数据追加到文件,如果文件不存在则创建该文件。data 可以是字符串或 <Buffer>

mode 选项仅影响新创建的文件。有关更多详细信息,请参阅 fs.open()

js
import { appendFileSync } from 'node:fs'

try {
  appendFileSync('message.txt', 'data to append')
  console.log('The "data to append" was appended to file!')
} catch (err) {
  /* 处理错误 */
}

如果 options 是一个字符串,则它指定编码:

js
import { appendFileSync } from 'node:fs'

appendFileSync('message.txt', 'data to append', 'utf8')

path 可以指定为已打开以进行追加(使用 fs.open()fs.openSync())的数字文件描述符。文件描述符不会自动关闭。

js
import { openSync, closeSync, appendFileSync } from 'node:fs'

let fd

try {
  fd = openSync('message.txt', 'a')
  appendFileSync(fd, 'data to append', 'utf8')
} catch (err) {
  /* 处理错误 */
} finally {
  if (fd !== undefined) closeSync(fd)
}

fs.chmodSync(path, mode)

[历史]

版本变更
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.6.7新增于:v0.6.7

更多详细信息,请参阅此 API 的异步版本的文档:fs.chmod()

更多细节请参考 POSIX chmod(2) 文档。

fs.chownSync(path, uid, gid)

[历史]

版本变更
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.97新增于:v0.1.97

同步更改文件的拥有者和组。返回 undefined。这是 fs.chown() 的同步版本。

更多细节请参考 POSIX chown(2) 文档。

fs.closeSync(fd)

新增于: v0.1.21

关闭文件描述符。返回 undefined

在任何其他 fs 操作正在使用任何文件描述符 (fd) 时调用 fs.closeSync() 可能会导致未定义的行为。

更多详情请参见 POSIX close(2) 文档。

fs.copyFileSync(src, dest[, mode])

[历史]

版本变更
v14.0.0flags 参数更改为 mode 并强制执行更严格的类型验证。
v8.5.0新增于: v8.5.0

同步地将 src 复制到 dest。默认情况下,如果 dest 已存在,则会被覆盖。返回 undefined。Node.js 并不保证复制操作的原子性。如果目标文件打开写入后发生错误,Node.js 将尝试删除目标文件。

mode 是一个可选整数,用于指定复制操作的行为。可以创建一个由两个或多个值的按位或构成的掩码(例如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE)。

  • fs.constants.COPYFILE_EXCL: 如果 dest 已存在,则复制操作将失败。
  • fs.constants.COPYFILE_FICLONE: 复制操作将尝试创建一个写时复制 reflink。如果平台不支持写时复制,则使用回退复制机制。
  • fs.constants.COPYFILE_FICLONE_FORCE: 复制操作将尝试创建一个写时复制 reflink。如果平台不支持写时复制,则操作将失败。
js
import { copyFileSync, constants } from 'node:fs'

// destination.txt 将被创建或覆盖(默认)。
copyFileSync('source.txt', 'destination.txt')
console.log('source.txt 已复制到 destination.txt')

// 使用 COPYFILE_EXCL,如果 destination.txt 存在,则操作将失败。
copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL)

fs.cpSync(src, dest[, options])

[历史]

版本变更
v22.3.0此 API 不再是实验性的。
v20.1.0, v18.17.0接受额外的 mode 选项,以指定复制行为,作为 fs.copyFile()mode 参数。
v17.6.0, v16.15.0接受额外的 verbatimSymlinks 选项,以指定是否对符号链接执行路径解析。
v16.7.0新增于:v16.7.0
  • src <字符串> | <URL> 要复制的源路径。

  • dest <字符串> | <URL> 要复制到的目标路径。

  • options <对象>

    • dereference <布尔值> 取消符号链接的引用。默认值: false

    • errorOnExist <布尔值>forcefalse,且目标存在时,抛出错误。默认值: false

    • filter <函数> 用于筛选复制的文件/目录的函数。返回 true 以复制项目,返回 false 以忽略它。忽略目录时,其所有内容也将被跳过。默认值: undefined

    • src <字符串> 要复制的源路径。

    • dest <字符串> 要复制到的目标路径。

    • 返回值: <布尔值> 任何可以强制转换为 boolean 的非 Promise 值。

    • force <布尔值> 覆盖现有文件或目录。如果将此设置为 false 且目标存在,则复制操作将忽略错误。使用 errorOnExist 选项更改此行为。默认值: true

    • mode <整数> 复制操作的修饰符。默认值: 0。参见 fs.copyFileSync()mode 标志。

    • preserveTimestamps <布尔值>true 时,将保留来自 src 的时间戳。默认值: false

    • recursive <布尔值> 递归复制目录 默认值: false

    • verbatimSymlinks <布尔值>true 时,将跳过符号链接的路径解析。默认值: false

同步地将整个目录结构从 src 复制到 dest,包括子目录和文件。

将目录复制到另一个目录时,不支持通配符,行为类似于 cp dir1/ dir2/

fs.existsSync(path)

[历史]

版本变更
v7.6.0path 参数可以使用使用 file: 协议的 WHATWG URL 对象。
v0.1.21v0.1.21 版本中添加

如果路径存在,则返回 true,否则返回 false

有关详细信息,请参阅此 API 的异步版本的文档:fs.exists()

fs.exists() 已弃用,但 fs.existsSync() 未弃用。fs.exists()callback 参数接受与其他 Node.js 回调不一致的参数。fs.existsSync() 不使用回调。

js
import { existsSync } from 'node:fs'

if (existsSync('/etc/passwd')) console.log('路径存在。')

fs.fchmodSync(fd, mode)

新增于: v0.4.7

设置文件的权限。返回 undefined

更多详情请参见 POSIX fchmod(2) 文档。

fs.fchownSync(fd, uid, gid)

新增于: v0.4.7

设置文件的所有者。返回 undefined

更多详情请参见 POSIX fchown(2) 文档。

fs.fdatasyncSync(fd)

自 v0.1.96 版本起加入

强制将当前与文件关联的所有已排队的 I/O 操作提交到操作系统的同步 I/O 完成状态。有关详细信息,请参阅 POSIX fdatasync(2) 文档。返回 undefined

fs.fstatSync(fd[, options])

[历史记录]

版本变更
v10.5.0接受一个额外的 options 对象来指定返回的数值是否应为 bigint。
v0.1.95自 v0.1.95 版本起加入

检索文件描述符的 <fs.Stats>

有关更多详细信息,请参阅 POSIX fstat(2) 文档。

fs.fsyncSync(fd)

新增于:v0.1.96

请求将打开的文件描述符的所有数据刷新到存储设备。具体的实现方式取决于操作系统和设备。有关更多详细信息,请参阅 POSIX fsync(2) 文档。返回 undefined

fs.ftruncateSync(fd[, len])

新增于:v0.8.6

截断文件描述符。返回 undefined

有关详细信息,请参阅此 API 的异步版本的文档:fs.ftruncate()

fs.futimesSync(fd, atime, mtime)

[历史]

版本变更
v4.1.0现在允许使用数字字符串、NaNInfinity 作为时间说明符。
v0.4.2新增于:v0.4.2

fs.futimes() 的同步版本。返回 undefined

fs.globSync(pattern[, options])

[历史]

版本变更
v22.2.0添加对 withFileTypes 选项的支持。
v22.0.0在 v22.0.0 版本中添加

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

  • pattern <字符串> | <字符串数组>

  • options <对象>

    • cwd <字符串> 当前工作目录。默认值: process.cwd()
    • exclude <函数> 用于过滤文件/目录的函数。返回 true 表示排除该项,返回 false 表示包含该项。默认值: undefined
    • withFileTypes <布尔值> 如果 glob 应将路径作为 Dirents 返回,则为 true,否则为 false默认值: false
  • 返回值: <字符串数组> 与模式匹配的文件路径。

js
import { globSync } from 'node:fs'

console.log(globSync('**/*.js'))
js
const { globSync } = require('node:fs')

console.log(globSync('**/*.js'))

fs.lchmodSync(path, mode)

自 v0.4.7 版本起已弃用

更改符号链接的权限。返回 undefined

此方法仅在 macOS 上实现。

更多详情,请参见 POSIX lchmod(2) 文档。

fs.lchownSync(path, uid, gid)

[历史]

版本变更
v10.6.0此 API 不再弃用。
v0.4.7仅文档弃用。

设置路径的所有者。返回 undefined

更多详情,请参见 POSIX lchown(2) 文档。

fs.lutimesSync(path, atime, mtime)

新增于:v14.5.0, v12.19.0

更改由 path 引用的符号链接的文件系统时间戳。返回 undefined,或者在参数不正确或操作失败时抛出异常。这是 fs.lutimes() 的同步版本。

fs.linkSync(existingPath, newPath)

[历史]

版本变更
v7.6.0existingPathnewPath 参数可以使用使用 file: 协议的 WHATWG URL 对象。当前支持仍处于 实验 阶段。
v0.1.31新增于: v0.1.31

existingPath 创建一个指向 newPath 的新链接。更多详情请参见 POSIX link(2) 文档。返回 undefined

fs.lstatSync(path[, options])

[历史]

版本变更
v15.3.0, v14.17.0接受 throwIfNoEntry 选项以指定如果条目不存在是否应该抛出异常。
v10.5.0接受额外的 options 对象以指定返回的数值是否应该是大整数。
v7.6.0path 参数可以使用使用 file: 协议的 WHATWG URL 对象。
v0.1.30新增于: v0.1.30

检索由 path 指向的符号链接的 <fs.Stats>

更多详情请参见 POSIX lstat(2) 文档。

fs.mkdirSync(path[, options])

[历史]

版本变更
v13.11.0, v12.17.0recursive 模式下,现在返回第一个创建的路径。
v10.12.0第二个参数现在可以是一个包含 recursivemode 属性的 options 对象。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v0.1.21添加于:v0.1.21

同步创建目录。返回 undefined,或者如果 recursivetrue,则返回创建的第一个目录路径。这是 fs.mkdir() 的同步版本。

更多详情,请参阅 POSIX mkdir(2) 文档。

fs.mkdtempSync(prefix[, options])

[历史]

版本变更
v20.6.0, v18.19.0prefix 参数现在接受缓冲区和 URL。
v16.5.0, v14.18.0prefix 参数现在接受空字符串。
v5.10.0新增于:v5.10.0

返回创建的目录路径。

有关详细信息,请参阅此 API 的异步版本的文档:fs.mkdtemp()

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,用于指定要使用的字符编码。

fs.opendirSync(path[, options])

[历史]

版本变更
v20.1.0, v18.17.0添加了 recursive 选项。
v13.1.0, v12.16.0引入了 bufferSize 选项。
v12.12.0v12.12.0 版本中添加

同步打开目录。参见 opendir(3)

创建一个 <fs.Dir>,其中包含所有用于从目录读取和清理目录的后续函数。

encoding 选项在打开目录和后续读取操作时设置 path 的编码。

fs.openSync(path[, flags[, mode]])

[历史]

版本变更
v11.1.0flags 参数现在是可选的,默认为 'r'
v9.9.0现在支持 asas+ 标志。
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.21新增于:v0.1.21

返回一个表示文件描述符的整数。

有关详细信息,请参阅此 API 的异步版本的文档:fs.open()

fs.readdirSync(path[, options])

[历史]

版本变更
v20.1.0, v18.17.0添加了 recursive 选项。
v10.10.0添加了新选项 withFileTypes
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.21v0.1.21 版本添加

读取目录的内容。

有关更多详细信息,请参阅 POSIX readdir(3) 文档。

可选的 options 参数可以是指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定用于返回的文件名的字符编码。如果将 encoding 设置为 'buffer',则返回的文件名将作为 <Buffer> 对象传递。

如果将 options.withFileTypes 设置为 true,则结果将包含 <fs.Dirent> 对象。

fs.readFileSync(path[, options])

[历史]

版本变更
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v5.0.0path 参数现在可以是文件描述符。
v0.1.8v0.1.8 版本中添加

返回 path 的内容。

有关详细信息,请参阅此 API 的异步版本的文档:fs.readFile()

如果指定了 encoding 选项,则此函数返回一个字符串。否则,它返回一个缓冲区。

类似于 fs.readFile(),当路径是目录时,fs.readFileSync() 的行为是特定于平台的。

js
import { readFileSync } from 'node:fs'

// macOS、Linux 和 Windows
readFileSync('<directory>')
// => [Error: EISDIR: 对目录的非法操作,读取 <directory>]

// FreeBSD
readFileSync('<directory>') // => <data>

fs.readlinkSync(path[, options])

[历史]

版本变更
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.31v0.1.31 版本新增

返回符号链接的字符串值。

更多详情,请参考 POSIX readlink(2) 文档。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,用于指定返回的链接路径的字符编码。如果将 encoding 设置为 'buffer',则返回的链接路径将作为 <Buffer> 对象传递。

fs.readSync(fd, buffer, offset, length[, position])

[历史]

版本变更
v10.10.0buffer 参数现在可以是任何 TypedArrayDataView
v6.0.0length 参数现在可以是 0
v0.1.21新增于:v0.1.21

返回读取的 bytesRead 数。

更多详细信息,请参阅此 API 的异步版本的文档:fs.read()

fs.readSync(fd, buffer[, options])

[历史]

版本变更
v13.13.0, v12.17.0可传递选项对象,使偏移量、长度和位置成为可选参数。
v13.13.0, v12.17.0新增于:v13.13.0, v12.17.0

返回读取的字节数 bytesRead

类似于上面的 fs.readSync 函数,此版本接受可选的 options 对象。如果未指定 options 对象,则将使用上述默认值。

有关详细信息,请参阅此 API 的异步版本的文档:fs.read()

fs.readvSync(fd, buffers[, position])

Added in: v13.13.0, v12.17.0

更多详细信息,请参阅此 API 的异步版本的文档:fs.readv()

fs.realpathSync(path[, options])

[历史]

版本变更
v8.0.0添加了管道/套接字解析支持。
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v6.4.0realpathSync 现在可以在 Windows 上的各种极端情况下再次工作。
v6.0.0cache 参数已移除。
v0.1.31新增于:v0.1.31

返回解析后的路径名。

更多详细信息,请参阅此 API 的异步版本的文档:fs.realpath()

fs.realpathSync.native(path[, options])

新增于: v9.2.0

同步 realpath(3)

仅支持可转换为 UTF8 字符串的路径。

可选的 options 参数可以是一个指定编码的字符串,或者是一个包含 encoding 属性的对象,该属性指定用于返回路径的字符编码。如果将 encoding 设置为 'buffer',则返回的路径将作为 <Buffer> 对象传递。

在 Linux 上,当 Node.js 链接到 musl libc 时,必须将 procfs 文件系统安装在 /proc 上才能使此函数正常工作。Glibc 没有此限制。

fs.renameSync(oldPath, newPath)

[历史]

版本变更
v7.6.0oldPathnewPath 参数可以是使用 file: 协议的 WHATWG URL 对象。目前支持仍处于实验阶段。
v0.1.21添加于:v0.1.21

将文件从 oldPath 重命名为 newPath。返回 undefined

更多详情请参见 POSIX rename(2) 文档。

fs.rmdirSync(path[, options])

[历史]

版本变更
v16.0.0path 为文件的路径上使用 fs.rmdirSync(path, { recursive: true }) 将不再被允许,并在 Windows 上返回 ENOENT 错误,在 POSIX 上返回 ENOTDIR 错误。
v16.0.0path 不存在的路径上使用 fs.rmdirSync(path, { recursive: true }) 将不再被允许,并将返回 ENOENT 错误。
v16.0.0recursive 选项已弃用,使用它会触发弃用警告。
v14.14.0recursive 选项已弃用,请改用 fs.rmSync
v13.3.0, v12.16.0maxBusyTries 选项已重命名为 maxRetries,其默认值为 0。emfileWait 选项已被移除,EMFILE 错误使用与其他错误相同的重试逻辑。现在支持 retryDelay 选项。现在重试 ENFILE 错误。
v12.10.0现在支持 recursivemaxBusyTriesemfileWait 选项。
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.21添加于:v0.1.21
  • path <字符串> | <Buffer> | <URL>
  • options <对象>
    • maxRetries <整数> 如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 将使用线性回退等待(每次尝试等待时间增加 retryDelay 毫秒)来重试操作。此选项表示重试次数。如果 recursive 选项不是 true,则忽略此选项。默认值:0
    • recursive <布尔值> 如果为 true,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值:false已弃用。
    • retryDelay <整数> 重试之间等待的时间(毫秒)。如果 recursive 选项不是 true,则忽略此选项。默认值:100

同步 rmdir(2)。返回 undefined

在文件(而不是目录)上使用 fs.rmdirSync() 将在 Windows 上导致 ENOENT 错误,在 POSIX 上导致 ENOTDIR 错误。

要获得类似于 rm -rf Unix 命令的行为,请使用 fs.rmSync() 并设置选项 { recursive: true, force: true }

fs.rmSync(path[, options])

[历史]

版本变更
v17.3.0, v16.14.0path 参数可以使用使用 file: 协议的 WHATWG URL 对象。
v14.14.0v14.14.0 中添加
  • path <字符串> | <Buffer> | <URL>
  • options <对象>
    • force <布尔值> 当值为 true 时,如果 path 不存在,则忽略异常。默认值: false
    • maxRetries <整数> 如果遇到 EBUSYEMFILEENFILEENOTEMPTYEPERM 错误,Node.js 将重试该操作,每次重试的等待时间增加 retryDelay 毫秒的线性回退等待时间。此选项表示重试次数。如果 recursive 选项不是 true,则忽略此选项。默认值: 0
    • recursive <布尔值> 如果为 true,则执行递归目录删除。在递归模式下,操作会在失败时重试。默认值: false
    • retryDelay <整数> 重试之间等待的时间(毫秒)。如果 recursive 选项不是 true,则忽略此选项。默认值: 100

同步删除文件和目录(基于标准 POSIX rm 实用程序)。返回 undefined

fs.statSync(path[, options])

[历史]

版本变更
v15.3.0, v14.17.0接受 throwIfNoEntry 选项以指定如果条目不存在是否应抛出异常。
v10.5.0接受附加的 options 对象以指定返回的数值是否应为 bigint。
v7.6.0path 参数可以使用 file: 协议使用 WHATWG URL 对象。
v0.1.21在 v0.1.21 中添加

检索路径的 <fs.Stats>

fs.statfsSync(path[, options])

新增于: v19.6.0, v18.15.0

同步 statfs(2)。返回包含 path 的已挂载文件系统的信息。

如果发生错误,err.code 将是 常见系统错误 之一。

fs.symlinkSync(target, path[, type])

[历史]

版本变更
v12.0.0如果 type 参数未定义,Node 将自动检测 target 类型并自动选择 dirfile
v7.6.0targetpath 参数可以使用 file: 协议的 WHATWG URL 对象。目前支持仍处于 实验 阶段。
v0.1.31新增于: v0.1.31

返回值为 undefined

有关详细信息,请参阅此 API 的异步版本的文档:fs.symlink()

fs.truncateSync(path[, len])

新增于:v0.8.6

截断文件。返回 undefined。文件描述符也可以作为第一个参数传递。在这种情况下,将调用 fs.ftruncateSync()

传递文件描述符已被弃用,将来可能会导致抛出错误。

fs.unlinkSync(path)

[历史]

版本变更
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v0.1.21新增于:v0.1.21

同步 unlink(2)。返回 undefined

fs.utimesSync(path, atime, mtime)

[历史]

版本变更
v8.0.0NaNInfinity-Infinity 不再是有效的时标说明符。
v7.6.0path 参数可以使用 file: 协议的 WHATWG URL 对象。
v4.1.0数字字符串、NaNInfinity 现在允许作为时标说明符。
v0.4.2新增于:v0.4.2

返回 undefined

更多详细信息,请参阅此 API 的异步版本的文档:fs.utimes()

fs.writeFileSync(file, data[, options])

[历史记录]

版本变更
v21.0.0, v20.10.0现在支持 flush 选项。
v19.0.0不再支持将具有自身 toString 函数的对象传递给 data 参数。
v17.8.0将具有自身 toString 函数的对象传递给 data 参数已被弃用。
v14.12.0data 参数将序列化具有显式 toString 函数的对象。
v14.0.0data 参数将不再强制将不支持的输入转换为字符串。
v10.10.0data 参数现在可以是任何 TypedArrayDataView
v7.4.0data 参数现在可以是 Uint8Array
v5.0.0file 参数现在可以是文件描述符。
v0.1.29添加于:v0.1.29

返回 undefined

mode 选项仅影响新创建的文件。有关更多详细信息,请参阅 fs.open()

有关详细信息,请参阅此 API 的异步版本的文档:fs.writeFile()

fs.writeSync(fd, buffer, offset[, length[, position]])

[历史]

版本变更
v14.0.0buffer 参数不再强制将不支持的输入转换为字符串。
v10.10.0buffer 参数现在可以是任何 TypedArrayDataView
v7.4.0buffer 参数现在可以是 Uint8Array
v7.2.0offsetlength 参数现在是可选的。
v0.1.21在 v0.1.21 中添加

有关详细信息,请参阅此 API 的异步版本的文档:fs.write(fd, buffer...)

fs.writeSync(fd, buffer[, options])

新增于:v18.3.0, v16.17.0

更多详细信息,请参阅此 API 的异步版本的文档:fs.write(fd, buffer...)

fs.writeSync(fd, string[, position[, encoding]])

[历史]

版本变更
v14.0.0string 参数不再强制将不支持的输入转换为字符串。
v7.2.0position 参数现在可选。
v0.11.5新增于:v0.11.5

更多详细信息,请参阅此 API 的异步版本的文档:fs.write(fd, string...)

fs.writevSync(fd, buffers[, position])

新增于:v12.9.0

更多详细信息,请参阅此 API 的异步版本的文档: fs.writev()

常用对象

常用对象由所有文件系统 API 变体(Promise、回调和同步)共享。

类:fs.Dir

新增于:v12.12.0

表示目录流的类。

fs.opendir()fs.opendirSync()fsPromises.opendir() 创建。

js
import { opendir } from 'node:fs/promises'

try {
  const dir = await opendir('./')
  for await (const dirent of dir) console.log(dirent.name)
} catch (err) {
  console.error(err)
}

使用异步迭代器时, <fs.Dir> 对象将在迭代器退出后自动关闭。

dir.close()

新增于:v12.12.0

异步关闭目录的基础资源句柄。后续读取将导致错误。

资源关闭后,将返回一个已完成的 Promise。

dir.close(callback)

[历史记录]

版本变更
v18.0.0将无效的回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v12.12.0新增于:v12.12.0

异步关闭目录的基础资源句柄。后续读取将导致错误。

资源句柄关闭后,将调用 callback

dir.closeSync()

新增于:v12.12.0

同步关闭目录的基础资源句柄。后续读取将导致错误。

dir.path

新增于:v12.12.0

此目录的只读路径,与提供给fs.opendir()fs.opendirSync(),或fsPromises.opendir()的路径相同。

dir.read()

新增于:v12.12.0

异步地通过readdir(3) 读取下一个目录项作为 <fs.Dirent>

返回一个 Promise,该 Promise 将以 <fs.Dirent> 完成,如果不再有目录项可读取,则以 null 完成。

此函数返回的目录项的顺序与操作系统底层目录机制提供的顺序无关。在迭代目录期间添加或删除的条目可能不会包含在迭代结果中。

dir.read(callback)

新增于:v12.12.0

异步地通过 readdir(3) 读取下一个目录项作为 <fs.Dirent>

读取完成后,将使用 <fs.Dirent> 调用 callback,如果没有任何更多目录项要读取,则为 null

此函数返回的目录项没有特定顺序,因为它是操作系统底层目录机制提供的。在迭代目录时添加或删除的条目可能不包含在迭代结果中。

dir.readSync()

新增于: v12.12.0

同步读取下一个目录项为 <fs.Dirent>。更多细节请参考 POSIX readdir(3) 文档。

如果没有更多目录项可读,则返回 null

此函数返回的目录项顺序不定,取决于操作系统底层的目录机制。在迭代目录期间添加或删除的条目可能不会包含在迭代结果中。

dir[Symbol.asyncIterator]()

新增于: v12.12.0

异步迭代目录,直到所有条目都被读取。更多细节请参考 POSIX readdir(3) 文档。

异步迭代器返回的条目始终为 <fs.Dirent>dir.read() 中的 null 情况在内部处理。

请参见 <fs.Dir> 获取示例。

此迭代器返回的目录项顺序不定,取决于操作系统底层的目录机制。在迭代目录期间添加或删除的条目可能不会包含在迭代结果中。

类: fs.Dirent

新增于: v10.10.0

目录项的表示,可以是目录中的文件或子目录,由读取 <fs.Dir> 返回。目录项是文件名和文件类型对的组合。

此外,当 fs.readdir()fs.readdirSync() 使用 withFileTypes 选项设置为 true 调用时,生成的数组将填充 <fs.Dirent> 对象,而不是字符串或 <Buffer> 对象。

dirent.isBlockDevice()

新增于: v10.10.0

如果 <fs.Dirent> 对象描述的是块设备,则返回 true

dirent.isCharacterDevice()

新增于: v10.10.0

如果 <fs.Dirent> 对象描述的是字符设备,则返回 true

dirent.isDirectory()

新增于:v10.10.0

如果 <fs.Dirent> 对象描述的是一个文件系统目录,则返回 true

dirent.isFIFO()

新增于:v10.10.0

如果 <fs.Dirent> 对象描述的是一个先进先出 (FIFO) 管道,则返回 true

dirent.isFile()

新增于:v10.10.0

如果 <fs.Dirent> 对象描述的是一个普通文件,则返回 true

dirent.isSocket()

新增于:v10.10.0

如果 <fs.Dirent> 对象描述的是一个套接字,则返回 true

新增于: v10.10.0

如果 <fs.Dirent> 对象描述的是符号链接,则返回 true

dirent.name

新增于: v10.10.0

<fs.Dirent> 对象引用的文件名。此值的类型由传递给 fs.readdir()fs.readdirSync()options.encoding 确定。

dirent.parentPath

新增于: v21.4.0, v20.12.0, v18.20.0

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

<fs.Dirent> 对象引用的文件的父目录路径。

dirent.path

[历史]

版本变更
v23.2.0该属性不再是只读的。
v23.0.0访问此属性会发出警告。它现在是只读的。
v21.5.0, v20.12.0, v18.20.0自此版本起已弃用: v21.5.0, v20.12.0, v18.20.0
v20.1.0, v18.17.0新增于: v20.1.0, v18.17.0

[稳定性: 0 - 已弃用]

稳定性: 0 稳定性: 0 - 已弃用: 请改用 dirent.parentPath

dirent.parentPath 的别名。

类: fs.FSWatcher

新增于: v0.5.8

成功调用 fs.watch() 方法将返回一个新的 <fs.FSWatcher> 对象。

所有 <fs.FSWatcher> 对象都会在监视的特定文件被修改时发出 'change' 事件。

事件:'change'

新增于:v0.5.8

当监视的目录或文件发生更改时发出。更多详情请参见 fs.watch()

根据操作系统的支持情况,filename 参数可能不会提供。如果提供了 filename,则如果使用 encoding 选项设置为 'buffer' 调用 fs.watch(),则它将作为 <Buffer> 提供,否则 filename 将是一个 UTF-8 字符串。

js
import { watch } from 'node:fs'
// 通过 fs.watch() 监听器处理的示例
watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
  if (filename) {
    console.log(filename)
    // 打印:<Buffer ...>
  }
})

事件: 'close'

新增于: v10.0.0

当观察程序停止观察更改时发出。已关闭的 <fs.FSWatcher> 对象在事件处理程序中不再可用。

事件: 'error'

新增于: v0.5.8

当观察文件时发生错误时发出。已出错的 <fs.FSWatcher> 对象在事件处理程序中不再可用。

watcher.close()

新增于: v0.5.8

停止观察给定 <fs.FSWatcher> 上的更改。停止后, <fs.FSWatcher> 对象将不再可用。

watcher.ref()

新增于: v14.3.0, v12.20.0

调用时,请求 Node.js 事件循环只要 <fs.FSWatcher> 处于活动状态就不要退出。多次调用 watcher.ref() 将不会有任何影响。

默认情况下,所有 <fs.FSWatcher> 对象都被“引用”,因此通常不需要调用 watcher.ref(),除非之前已调用 watcher.unref()

watcher.unref()

新增于:v14.3.0, v12.20.0

调用此方法后,活跃的 <fs.FSWatcher> 对象将不再需要 Node.js 事件循环保持活动状态。如果没有其他活动保持事件循环运行,则在 <fs.FSWatcher> 对象的回调被调用之前,进程可能会退出。多次调用 watcher.unref() 将不会产生任何效果。

类:fs.StatWatcher

新增于:v14.3.0, v12.20.0

成功调用 fs.watchFile() 方法将返回一个新的 <fs.StatWatcher> 对象。

watcher.ref()

新增于:v14.3.0, v12.20.0

调用此方法后,请求 Node.js 事件循环 不要 退出,只要 <fs.StatWatcher> 保持活跃状态。多次调用 watcher.ref() 将不会产生任何效果。

默认情况下,所有 <fs.StatWatcher> 对象都被“引用”(ref'ed),因此通常无需调用 watcher.ref(),除非之前已调用 watcher.unref()

watcher.unref()

新增于:v14.3.0, v12.20.0

调用此方法后,活动的 <fs.StatWatcher> 对象将不再需要 Node.js 事件循环保持活动状态。如果没有任何其他活动使事件循环保持运行,则在 <fs.StatWatcher> 对象的回调被调用之前,进程可能会退出。多次调用 watcher.unref() 不会产生任何影响。

类:fs.ReadStream

新增于:v0.1.93

<fs.ReadStream> 的实例是使用 fs.createReadStream() 函数创建和返回的。

事件:'close'

新增于:v0.1.93

<fs.ReadStream> 的底层文件描述符已关闭时发出。

事件:'open'

新增于:v0.1.93

<fs.ReadStream> 的文件描述符已打开时发出。

事件: 'ready'

新增于: v9.11.0

<fs.ReadStream> 准备好使用时发出。

紧随 'open' 事件之后触发。

readStream.bytesRead

新增于: v6.4.0

到目前为止已读取的字节数。

readStream.path

新增于: v0.1.93

流读取的文件路径,在 fs.createReadStream() 的第一个参数中指定。如果 path 以字符串形式传递,则 readStream.path 将为字符串。如果 path<Buffer> 形式传递,则 readStream.path 将为 <Buffer>。如果指定了 fd,则 readStream.path 将为 undefined

readStream.pending

新增于: v11.2.0, v10.16.0

如果底层文件尚未打开,则此属性为 true,即在发出 'ready' 事件之前。

类: fs.Stats

[历史]

版本变更
v22.0.0, v20.13.0公共构造函数已弃用。
v8.1.0添加了作为数字的时间。
v0.1.21添加于:v0.1.21

<fs.Stats> 对象提供有关文件的信息。

fs.stat()fs.lstat()fs.fstat() 及其同步对应方法返回的对象属于此类型。如果传递给这些方法的 options 中的 bigint 为 true,则数值将为 bigint 而不是 number,并且对象将包含附加了 Ns 后缀的纳秒精度属性。Stat 对象不能直接使用 new 关键字创建。

bash
Stats {
  dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atimeMs: 1318289051000.1,
  mtimeMs: 1318289051000.1,
  ctimeMs: 1318289051000.1,
  birthtimeMs: 1318289051000.1,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

bigint 版本:

bash
BigIntStats {
  dev: 2114n,
  ino: 48064969n,
  mode: 33188n,
  nlink: 1n,
  uid: 85n,
  gid: 100n,
  rdev: 0n,
  size: 527n,
  blksize: 4096n,
  blocks: 8n,
  atimeMs: 1318289051000n,
  mtimeMs: 1318289051000n,
  ctimeMs: 1318289051000n,
  birthtimeMs: 1318289051000n,
  atimeNs: 1318289051000000000n,
  mtimeNs: 1318289051000000000n,
  ctimeNs: 1318289051000000000n,
  birthtimeNs: 1318289051000000000n,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

stats.isBlockDevice()

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是块设备,则返回 true

stats.isCharacterDevice()

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是字符设备,则返回 true

stats.isDirectory()

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是文件系统目录,则返回 true

如果 <fs.Stats> 对象是通过调用 fs.lstat() 获取的,并且该对象指向一个解析为目录的符号链接,则此方法将返回 false。这是因为 fs.lstat() 返回的是符号链接本身的信息,而不是它解析到的路径的信息。

stats.isFIFO()

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是一个先进先出 (FIFO) 管道,则返回 true

stats.isFile()

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是一个普通文件,则返回 true

stats.isSocket()

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是一个套接字,则返回 true

新增于: v0.1.10

如果 <fs.Stats> 对象描述的是一个符号链接,则返回 true

此方法仅在使用 fs.lstat() 时有效。

stats.dev

包含文件的设备的数字标识符。

stats.ino

文件的特定于文件系统的“索引节点”编号。

stats.mode

描述文件类型和模式的位字段。

文件的硬链接数。

stats.uid

文件所有者的数字用户标识符 (POSIX)。

stats.gid

文件所属组的数字组标识符 (POSIX)。

stats.rdev

如果文件表示一个设备,则为数字设备标识符。

stats.size

文件的大小(以字节为单位)。

如果底层文件系统不支持获取文件大小,则此值为 0

stats.blksize

用于 I/O 操作的文件系统块大小。

stats.blocks

为此文件分配的块数。

stats.atimeMs

新增于:v8.1.0

表示上次访问此文件的时间戳,以自 POSIX 纪元以来的毫秒数表示。

stats.mtimeMs

新增于:v8.1.0

表示上次修改此文件的时间戳,以自 POSIX 纪元以来的毫秒数表示。

stats.ctimeMs

新增于: v8.1.0

表示文件状态最后一次更改的时间戳,以自 POSIX 纪元以来的毫秒数表示。

stats.birthtimeMs

新增于: v8.1.0

表示此文件创建时间的时间戳,以自 POSIX 纪元以来的毫秒数表示。

stats.atimeNs

新增于: v12.10.0

仅当将 bigint: true 传递给生成该对象的函数时才存在。表示此文件最后一次被访问的时间戳,以自 POSIX 纪元以来的纳秒数表示。

stats.mtimeNs

新增于:v12.10.0

仅当将 bigint: true 传递给生成该对象的函数时才存在。表示上次修改此文件的时间戳,以自 POSIX 纪元以来的纳秒数表示。

stats.ctimeNs

新增于:v12.10.0

仅当将 bigint: true 传递给生成该对象的函数时才存在。表示上次更改文件状态的时间戳,以自 POSIX 纪元以来的纳秒数表示。

stats.birthtimeNs

新增于:v12.10.0

仅当将 bigint: true 传递给生成该对象的函数时才存在。表示此文件创建时间的时间戳,以自 POSIX 纪元以来的纳秒数表示。

stats.atime

新增于: v0.11.13

指示上次访问此文件的的时间戳。

stats.mtime

新增于: v0.11.13

指示上次修改此文件的的时间戳。

stats.ctime

新增于: v0.11.13

指示上次更改文件状态的时间戳。

stats.birthtime

新增于: v0.11.13

指示此文件创建时间的时间戳。

Stat 时间值

atimeMsmtimeMsctimeMsbirthtimeMs 属性是数值,以毫秒为单位保存相应的时间。其精度取决于平台。当将 bigint: true 传递给生成该对象的的方法时,这些属性将是 bigint,否则将是 数字

atimeNsmtimeNsctimeNsbirthtimeNs 属性是 bigint,以纳秒为单位保存相应的时间。只有当将 bigint: true 传递给生成该对象的的方法时,它们才会出现。其精度取决于平台。

atimemtimectimebirthtimeDate 对象,它们是各种时间的替代表示形式。Date 和数值之间没有关联。赋值一个新的数值,或更改 Date 值,不会反映在相应的替代表示形式中。

stat 对象中的时间具有以下语义:

  • atime “访问时间”:上次访问文件数据的时间。被 mknod(2)utimes(2)read(2) 系统调用更改。
  • mtime “修改时间”:上次修改文件数据的时间。被 mknod(2)utimes(2)write(2) 系统调用更改。
  • ctime “更改时间”:上次更改文件状态(inode 数据修改)的时间。被 chmod(2)chown(2)link(2)mknod(2)rename(2)unlink(2)utimes(2)read(2)write(2) 系统调用更改。
  • birthtime “创建时间”:文件创建的时间。文件创建时设置一次。在无法获得 birthtime 的文件系统上,此字段可能改为保存 ctime1970-01-01T00:00Z(即 Unix 纪元时间戳 0)。在这种情况下,此值可能大于 atimemtime。在 Darwin 和其他 FreeBSD 变体上,如果使用 utimes(2) 系统调用将 atime 显式设置为早于当前 birthtime 的值,也会设置此值。

在 Node.js 0.12 之前,ctime 在 Windows 系统上保存 birthtime。从 0.12 开始,ctime 不是“创建时间”,在 Unix 系统上,它也从来都不是。

类: fs.StatFs

新增于: v19.6.0, v18.15.0

提供有关已挂载文件系统的信息。

fs.statfs()及其同步对应方法返回的对象为此类型。如果传递给这些方法的options中的biginttrue,则数值将为bigint而不是number

bash
StatFs {
  type: 1397114950,
  bsize: 4096,
  blocks: 121938943,
  bfree: 61058895,
  bavail: 61058895,
  files: 999,
  ffree: 1000000
}

bigint 版本:

bash
StatFs {
  type: 1397114950n,
  bsize: 4096n,
  blocks: 121938943n,
  bfree: 61058895n,
  bavail: 61058895n,
  files: 999n,
  ffree: 1000000n
}

statfs.bavail

新增于: v19.6.0, v18.15.0

可供非特权用户使用的空闲块。

statfs.bfree

新增于:v19.6.0, v18.15.0

文件系统中的空闲块。

statfs.blocks

新增于:v19.6.0, v18.15.0

文件系统中的总数据块数。

statfs.bsize

新增于:v19.6.0, v18.15.0

最佳传输块大小。

statfs.ffree

新增于:v19.6.0, v18.15.0

文件系统中的空闲文件节点数。

statfs.files

新增于:v19.6.0, v18.15.0

文件系统中的文件节点总数。

statfs.type

新增于:v19.6.0, v18.15.0

文件系统类型。

类:fs.WriteStream

新增于:v0.1.93

<fs.WriteStream> 的实例由 fs.createWriteStream() 函数创建并返回。

事件:'close'

新增于:v0.1.93

<fs.WriteStream> 的底层文件描述符已关闭时发出。

事件: 'open'

新增于: v0.1.93

<fs.WriteStream> 的文件打开时发出。

事件: 'ready'

新增于: v9.11.0

<fs.WriteStream> 准备好使用时发出。

紧随 'open' 后触发。

writeStream.bytesWritten

新增于: v0.4.7

到目前为止写入的字节数。不包括仍在排队等待写入的数据。

writeStream.close([callback])

新增于: v0.9.4

关闭 writeStream。可以选择接受一个回调函数,该函数将在 writeStream 关闭后执行。

writeStream.path

新增于: v0.1.93

流写入的文件路径,如同在 fs.createWriteStream() 的第一个参数中指定的那样。如果 path 以字符串形式传递,则 writeStream.path 将为字符串。如果 path<Buffer> 形式传递,则 writeStream.path 将为 <Buffer>

writeStream.pending

新增于: v11.2.0

如果底层文件尚未打开,则此属性为 true,即在发出 'ready' 事件之前。

fs.constants

返回一个包含文件系统操作常用常量的对象。

文件系统常量

以下常量由 fs.constantsfsPromises.constants 导出。

并非所有常量在所有操作系统上都可用;这对于 Windows 尤其重要,因为许多 POSIX 特定的定义在 Windows 上不可用。对于可移植的应用程序,建议在使用前检查其是否存在。

要使用多个常量,请使用按位或 | 运算符。

示例:

js
import { open, constants } from 'node:fs'

const { O_RDWR, O_CREAT, O_EXCL } = constants

open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
  // ...
})
文件访问常量

以下常量旨在用作传递给 fsPromises.access()fs.access()fs.accessSync()mode 参数。

常量描述
F_OK指示文件对调用进程可见的标志。这对于确定文件是否存在很有用,但没有说明 rwx 权限。如果未指定模式,则为默认值。
R_OK指示文件可被调用进程读取的标志。
W_OK指示文件可被调用进程写入的标志。
X_OK指示文件可被调用进程执行的标志。这在 Windows 上无效(行为类似于 fs.constants.F_OK)。

这些定义在 Windows 上也可用。

文件复制常量

以下常量旨在与 fs.copyFile() 一起使用。

常量描述
COPYFILE_EXCL如果存在,如果目标路径已存在,则复制操作将失败并报错。
COPYFILE_FICLONE如果存在,复制操作将尝试创建一个写时复制 reflink。如果底层平台不支持写时复制,则使用备用复制机制。
COPYFILE_FICLONE_FORCE如果存在,复制操作将尝试创建一个写时复制 reflink。如果底层平台不支持写时复制,则操作将失败并报错。

这些定义在 Windows 上也可用。

文件打开常量

以下常量旨在与 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 操作系统上可用。在其他操作系统上,此标志将被忽略。

在 Windows 上,仅可用 O_APPENDO_CREATO_EXCLO_RDONLYO_RDWRO_TRUNCO_WRONLYUV_FS_O_FILEMAP

文件类型常量

以下常量旨在与 <fs.Stats> 对象的 mode 属性一起使用,以确定文件的类型。

常量描述
S_IFMT用于提取文件类型代码的位掩码。
S_IFREG常规文件的类型常量。
S_IFDIR目录的类型常量。
S_IFCHR字符型设备文件的类型常量。
S_IFBLK块型设备文件的类型常量。
S_IFIFOFIFO/管道的类型常量。
S_IFLNK符号链接的类型常量。
S_IFSOCK套接字的类型常量。

在 Windows 上,仅可用 S_IFCHRS_IFDIRS_IFLNKS_IFMTS_IFREG

文件模式常量

以下常量旨在与 <fs.Stats> 对象的 mode 属性一起使用,以确定文件的访问权限。

常量描述
S_IRWXU文件模式,指示所有者可读、可写和可执行。
S_IRUSR文件模式,指示所有者可读。
S_IWUSR文件模式,指示所有者可写。
S_IXUSR文件模式,指示所有者可执行。
S_IRWXG文件模式,指示组可读、可写和可执行。
S_IRGRP文件模式,指示组可读。
S_IWGRP文件模式,指示组可写。
S_IXGRP文件模式,指示组可执行。
S_IRWXO文件模式,指示其他人可读、可写和可执行。
S_IROTH文件模式,指示其他人可读。
S_IWOTH文件模式,指示其他人可写。
S_IXOTH文件模式,指示其他人可执行。

在 Windows 上,仅可用 S_IRUSRS_IWUSR

备注

回调函数和基于 Promise 的操作的顺序

由于底层线程池异步执行这些操作,因此使用回调函数或基于 Promise 的方法时,无法保证其执行顺序。

例如,以下代码容易出错,因为 fs.stat() 操作可能在 fs.rename() 操作之前完成:

js
const fs = require('node:fs')

fs.rename('/tmp/hello', '/tmp/world', err => {
  if (err) throw err
  console.log('renamed complete')
})
fs.stat('/tmp/world', (err, stats) => {
  if (err) throw err
  console.log(`stats: ${JSON.stringify(stats)}`)
})

必须通过等待一个操作的结果后再调用另一个操作来正确排序操作:

js
import { rename, stat } from 'node:fs/promises'

const oldPath = '/tmp/hello'
const newPath = '/tmp/world'

try {
  await rename(oldPath, newPath)
  const stats = await stat(newPath)
  console.log(`stats: ${JSON.stringify(stats)}`)
} catch (error) {
  console.error('there was an error:', error.message)
}
js
const { rename, stat } = require('node:fs/promises')

;(async function (oldPath, newPath) {
  try {
    await rename(oldPath, newPath)
    const stats = await stat(newPath)
    console.log(`stats: ${JSON.stringify(stats)}`)
  } catch (error) {
    console.error('there was an error:', error.message)
  }
})('/tmp/hello', '/tmp/world')

或者,当使用回调 API 时,将 fs.stat() 调用移入 fs.rename() 操作的回调函数中:

js
import { rename, stat } from 'node:fs'

rename('/tmp/hello', '/tmp/world', err => {
  if (err) throw err
  stat('/tmp/world', (err, stats) => {
    if (err) throw err
    console.log(`stats: ${JSON.stringify(stats)}`)
  })
})
js
const { rename, stat } = require('node:fs/promises')

rename('/tmp/hello', '/tmp/world', err => {
  if (err) throw err
  stat('/tmp/world', (err, stats) => {
    if (err) throw err
    console.log(`stats: ${JSON.stringify(stats)}`)
  })
})

文件路径

大多数 fs 操作接受以字符串、<Buffer> 或使用 file: 协议的 <URL> 对象形式指定的文 件路径。

字符串路径

字符串路径被解释为识别绝对或相对文件名的 UTF-8 字符序列。相对路径将相对于调用 process.cwd() 所确定的当前工作目录解析。

在 POSIX 系统上使用绝对路径的示例:

js
import { open } from 'node:fs/promises'

let fd
try {
  fd = await open('/open/some/file.txt', 'r')
  // 对文件执行某些操作
} finally {
  await fd?.close()
}

在 POSIX 系统上使用相对路径的示例(相对于 process.cwd()):

js
import { open } from 'node:fs/promises'

let fd
try {
  fd = await open('file.txt', 'r')
  // 对文件执行某些操作
} finally {
  await fd?.close()
}

文件 URL 路径

新增于:v7.6.0

对于大多数 node:fs 模块函数,pathfilename 参数可以作为使用 file: 协议的 <URL> 对象传递。

js
import { readFileSync } from 'node:fs'

readFileSync(new URL('file:///tmp/hello'))

file: URL 始终是绝对路径。

平台特定注意事项

在 Windows 上,带有主机名的 file: <URL> 将转换为 UNC 路径,而带有驱动器盘符的 file: <URL> 将转换为本地绝对路径。没有主机名和驱动器盘符的 file: <URL> 将导致错误:

js
import { readFileSync } from 'node:fs'
// 在 Windows 上:

// - 带有主机名的 WHATWG 文件 URL 将转换为 UNC 路径
// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
readFileSync(new URL('file://hostname/p/a/t/h/file'))

// - 带有驱动器盘符的 WHATWG 文件 URL 将转换为绝对路径
// file:///C:/tmp/hello => C:\tmp\hello
readFileSync(new URL('file:///C:/tmp/hello'))

// - 没有主机名的 WHATWG 文件 URL 必须具有驱动器盘符
readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'))
readFileSync(new URL('file:///c/p/a/t/h/file'))
// TypeError [ERR_INVALID_FILE_URL_PATH]: 文件 URL 路径必须是绝对路径

带有驱动器盘符的 file: <URL> 必须在驱动器盘符之后立即使用 : 作为分隔符。使用其他分隔符将导致错误。

在所有其他平台上,带有主机名的 file: <URL> 不受支持,并将导致错误:

js
import { readFileSync } from 'node:fs'
// 在其他平台上:

// - 带有主机名的 WHATWG 文件 URL 不受支持
// file://hostname/p/a/t/h/file => 抛出异常!
readFileSync(new URL('file://hostname/p/a/t/h/file'))
// TypeError [ERR_INVALID_FILE_URL_PATH]: 必须是绝对路径

// - WHATWG 文件 URL 将转换为绝对路径
// file:///tmp/hello => /tmp/hello
readFileSync(new URL('file:///tmp/hello'))

具有编码斜杠字符的 file: <URL> 将在所有平台上导致错误:

js
import { readFileSync } from 'node:fs'

// 在 Windows 上
readFileSync(new URL('file:///C:/p/a/t/h/%2F'))
readFileSync(new URL('file:///C:/p/a/t/h/%2f'))
/* TypeError [ERR_INVALID_FILE_URL_PATH]: 文件 URL 路径不得包含编码的 \ 或 / 字符 */

// 在 POSIX 上
readFileSync(new URL('file:///p/a/t/h/%2F'))
readFileSync(new URL('file:///p/a/t/h/%2f'))
/* TypeError [ERR_INVALID_FILE_URL_PATH]: 文件 URL 路径不得包含编码的 / 字符 */

在 Windows 上,具有编码反斜杠的 file: <URL> 将导致错误:

js
import { readFileSync } from 'node:fs'

// 在 Windows 上
readFileSync(new URL('file:///C:/path/%5C'))
readFileSync(new URL('file:///C:/path/%5c'))
/* TypeError [ERR_INVALID_FILE_URL_PATH]: 文件 URL 路径不得包含编码的 \ 或 / 字符 */

Buffer 路径

使用 <Buffer> 指定的路径主要在某些将文件路径视为不透明字节序列的 POSIX 操作系统上很有用。在这些系统上,单个文件路径可能包含使用多种字符编码的子序列。与字符串路径一样,<Buffer> 路径可以是相对路径或绝对路径:

使用 POSIX 上的绝对路径的示例:

js
import { open } from 'node:fs/promises'
import { Buffer } from 'node:buffer'

let fd
try {
  fd = await open(Buffer.from('/open/some/file.txt'), 'r')
  // 对文件执行某些操作
} finally {
  await fd?.close()
}

Windows 上的每个驱动器的当前工作目录

在 Windows 上,Node.js 遵循每个驱动器的当前工作目录的概念。当使用没有反斜杠的驱动器路径时,可以观察到此行为。例如,fs.readdirSync('C:\\') 可能返回的结果与 fs.readdirSync('C:') 不同。有关更多信息,请参见此 MSDN 页面

文件描述符

在 POSIX 系统上,对于每个进程,内核都会维护一个当前打开的文件和资源表。每个打开的文件都会分配一个简单的数字标识符,称为文件描述符。在系统级别,所有文件系统操作都使用这些文件描述符来识别和跟踪每个特定文件。Windows 系统使用不同的但概念上类似的机制来跟踪资源。为了简化用户的操作,Node.js 隐藏了不同操作系统之间的差异,并为所有打开的文件分配一个数字文件描述符。

基于回调的fs.open()和同步的fs.openSync()方法打开文件并分配一个新的文件描述符。分配后,文件描述符可用于读取数据、写入数据或请求有关文件的信息。

操作系统限制了在任何给定时间可能打开的文件描述符数量,因此在操作完成后关闭描述符至关重要。否则会导致内存泄漏,最终导致应用程序崩溃。

js
import { open, close, fstat } from 'node:fs'

function closeFd(fd) {
  close(fd, err => {
    if (err) throw err
  })
}

open('/open/some/file.txt', 'r', (err, fd) => {
  if (err) throw err
  try {
    fstat(fd, (err, stat) => {
      if (err) {
        closeFd(fd)
        throw err
      }

      // 使用 stat

      closeFd(fd)
    })
  } catch (err) {
    closeFd(fd)
    throw err
  }
})

基于 Promise 的 API 使用 <FileHandle> 对象代替数字文件描述符。这些对象由系统更好地管理,以确保不会泄漏资源。但是,仍然需要在操作完成后关闭它们:

js
import { open } from 'node:fs/promises'

let file
try {
  file = await open('/open/some/file.txt', 'r')
  const stat = await file.stat()
  // 使用 stat
} finally {
  await file.close()
}

线程池使用

所有基于回调和 Promise 的文件系统 API(fs.FSWatcher() 除外)都使用 libuv 的线程池。这可能会对某些应用程序产生令人惊讶的负面性能影响。有关更多信息,请参阅UV_THREADPOOL_SIZE 文档。

文件系统标志

以下标志可在 flag 选项接受字符串的任何位置使用。

  • 'a': 以追加模式打开文件。如果文件不存在,则创建该文件。
  • 'ax': 与 'a' 相同,但如果路径存在则失败。
  • 'a+': 以读写追加模式打开文件。如果文件不存在,则创建该文件。
  • 'ax+': 与 'a+' 相同,但如果路径存在则失败。
  • 'as': 以同步模式打开文件进行追加。如果文件不存在,则创建该文件。
  • 'as+': 以同步模式打开文件进行读写追加。如果文件不存在,则创建该文件。
  • 'r': 以只读模式打开文件。如果文件不存在,则引发异常。
  • 'rs': 以同步模式打开文件进行读取。如果文件不存在,则引发异常。
  • 'r+': 以读写模式打开文件。如果文件不存在,则引发异常。
  • 'rs+': 以同步模式打开文件进行读写。指示操作系统绕过本地文件系统缓存。这主要用于打开 NFS 挂载上的文件,因为它允许跳过可能过时的本地缓存。这对 I/O 性能有非常大的影响,因此除非需要,否则不建议使用此标志。这不会将 fs.open()fsPromises.open() 转换为同步阻塞调用。如果需要同步操作,应使用类似 fs.openSync() 的方法。
  • 'w': 以写入模式打开文件。如果文件不存在,则创建该文件;如果文件存在,则截断该文件。
  • 'wx': 与 'w' 相同,但如果路径存在则失败。
  • 'w+': 以读写模式打开文件。如果文件不存在,则创建该文件;如果文件存在,则截断该文件。
  • 'wx+': 与 'w+' 相同,但如果路径存在则失败。

flag 也可以是数字,如open(2) 中所述;常用的常量可从 fs.constants 获取。在 Windows 上,标志会被转换为其等效标志(如果适用),例如 O_WRONLY 转换为 FILE_GENERIC_WRITE,或 O_EXCL|O_CREAT 转换为 CREATE_NEW,如 CreateFileW 所接受的那样。

独占标志 'x'open(2) 中的 O_EXCL 标志)会导致如果路径已存在,则操作返回错误。在 POSIX 系统上,如果路径是符号链接,即使链接指向不存在的路径,使用 O_EXCL 也会返回错误。独占标志可能无法与网络文件系统一起使用。

在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核会忽略位置参数,并将数据始终追加到文件的末尾。

修改文件而不是替换文件可能需要将 flag 选项设置为 'r+' 而不是默认的 'w'

某些标志的行为是特定于平台的。因此,如下例所示,在 macOS 和 Linux 上以 'a+' 标志打开目录将返回错误。相反,在 Windows 和 FreeBSD 上,将返回文件描述符或 FileHandle

js
// macOS 和 Linux
fs.open('<directory>', 'a+', (err, fd) => {
  // => [Error: EISDIR: illegal operation on a directory, open <directory>]
})

// Windows 和 FreeBSD
fs.open('<directory>', 'a+', (err, fd) => {
  // => null, <fd>
})

在 Windows 上,使用 'w' 标志(通过 fs.open()fs.writeFile()fsPromises.open())打开现有的隐藏文件将失败并返回 EPERM。可以使用 'r+' 标志打开现有的隐藏文件进行写入。

可以使用 fs.ftruncate()filehandle.truncate() 调用来重置文件内容。