Node.js API 之旅:深入 fs 模块之 FileHandle

393 阅读10分钟

FileHandle,即文件句柄,是 Node.js 文件系统模块中提供的一种用于操作文件的抽象对象,是 fs.promises API 中的一个类,用于表示打开的文件。在 Node.js 中,我们可以通过 fs.promises.open() 方法来打开一个文件,并获得该文件对应的 FileHandle 对象

FileHandle 的作用类似于我们平时在操作系统中所见到的文件句柄,实际上它就是为了方便地管理文件而存在的一种抽象机制。通过使用 FileHandle,我们可以更加方便高效地进行文件操作,并且避免因为多次打开和关闭文件而导致的资源浪费和性能问题。

文件句柄的概念有点抽象,可以把它想象成一把钥匙,这把钥匙可以打开一个特定的文件。只要你拥有这把钥匙,就可以对这个文件进行操作。文件句柄通常以对象或整数的形式表示。

FileHandle 对象提供了一些方法,比如 read()write()close() 等,用于读取、写入或关闭文件。我们也可以使用它来查询文件的属性(如文件大小、创建时间等)或设置文件属性(如修改文件的读写权限等)。

1. filehandle.close()

作用

用于关闭文件句柄,当使用 fsPromises.open() 打开文件时,会返回一个 FileHandle 实例。在完成文件操作(如读取、写入等)后,需要使用 filehandle.close() 方法关闭文件,以便释放系统资源,防止文件损坏和数据丢失。

示例


import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt')

  // 在此执行其他文件操作
} catch (err) {
  console.error('发生异常:', err)
} finally {
  await filehandle?.close()
  console.log('文件句柄成功关闭')
}

2. filehandle.writeFile(data, options)

作用

用于异步地将数据写入文件。

  • 如果文件已经存在,则替换该文件。
  • 如果文件不存在,自动创建一个新的文件并将数据写入该文件中。
  • 如果文件路径所在的目录不存在,将返回一个错误,需要先手动创建它所在的目录。

注意⚠:在 Promise 解析(或拒绝)之前多次使用 filehandle.writeFile() 写入同一文件是不安全的。如果在一个文件上调用了一个或多个 filehandle.write() 方法,然后再调用 filehandle.writeFile() 方法,那么数据将从当前位置写入到文件末尾,它并不总是从文件开头开始写入。

参数

  • datastringBufferTypedArrayDataViewAsyncIterableIterableStream\color{green}string | Buffer | TypedArray | DataView | AsyncIterable | Iterable | Stream 要写入文件的内容
  • options(可选):Objectstring\color{green}Object | string 如果为字符串,表示数据的字符编码;如果是一个对象,包含以下可选属性:
    • encoding(可选):指定写入数据的编码,默认为'utf8'

示例


import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'w')

  await filehandle.writeFile('你好 Node', 'utf8')
  console.log('数据已被成功写入')
} catch (err) {
  console.error('写入失败:', err)
} finally {
  await filehandle?.close()
}

3. filehandle.appendFile(data[, options])

filehandle.writeFile() 的别名

4. filehandle.chmod(mode)

作用

用于更改文件的访问权限。在 Unix 和 Unix-like 系统(如 Linux 和 macOS)中,文件权限决定了谁可以对文件执行读取、写入和执行操作。filehandle.chmod(mode) 允许你修改文件的权限,以便控制文件的访问。

参数

  • modeinteger\color{green}integer 表示要设置的文件权限,例如 0o755

mode 的值必须为一个八进制整数,表示要设置的文件权限。在 Unix 和 Unix-like 系统中(如 Linux 和 macOS),文件权限由一个 9 位的二进制数表示,分为 3 个权限组:文件所有者(owner)、文件所属组(group)以及其他用户(others)。每个权限组包含 3 位,分别表示读(read)、写(write)和执行(execute)权限。

权限可以用数字表示,从左到右分别是:

  1. 读:4
  2. 写:2
  3. 执行:1

每个权限组中的权限值可以通过将其权限相加来计算。例如,如果要为文件所有者设置读、写权限,权限值为 4(读)+ 2(写)= 6。

因此,mode 参数是一个 3 位的八进制数,每位分别表示文件所有者、文件所属组和其他用户的权限。例如,要将文件权限设置为允许文件所有者读取和写入,允许文件所属组和其他用户读取,可以使用以下权限模式:

  • 文件所有者:读 + 写 = 4 + 2 = 6
  • 文件所属组:读 = 4
  • 其他用户:读 = 4

将这些权限组合在一起,得到八进制数 0644。在 JavaScript 中,可以通过 0o644 表示。因此,filehandle.chmod(0o644) 可以将文件权限设置为上述权限。

以下是一些常用的权限模式:

  • 0o755:允许文件所有者读取、写入和执行;允许文件所属组和其他用户读取和执行
  • 0o644:允许文件所有者读取和写入;允许文件所属组和其他用户读取
  • 0o700:仅允许文件所有者读取、写入和执行

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r+')

  // 更改文件权限为 "0o755",即允许文件所有者进行读、写、执行操作,组和其他用户进行读和执行操作
  await filehandle.chmod(0o755)
  console.log('文件权限已成功更改')
} catch (error) {
  console.error('文件权限更改失败:', error)
} finally {
  await filehandle?.close()
}

5. filehandle.chown(uid, gid)

作用

用于更改文件的所有者(owner)和所属组(group)。

参数

  1. uidinteger\color{green}integer 用户 ID,表示新的文件所有者。通常在 Unix 和 Unix-like 系统(如 Linux 和 macOS)中,每个用户都有一个唯一的用户 ID。

  2. gidinteger\color{green}integer 组 ID,表示新的文件所属组。同样,在 Unix 和 Unix-like 系统中,每个组都有一个唯一的组 ID。

注意⚠:此操作需要管理员权限才能执行,否则可能会遇到权限错误。

示例


import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  fileHandle = await fsPromises.open('./fs/heihei.txt', 'r+')

  await fileHandle.chown(1000, 1000)
  await fileHandle.close()
  console.log('文件所有权已更改')
} catch (err) {
  console.error('文件所有权更改失败:', ${err})
} finally {
  await filehandle?.close()
}

6. filehandle.createReadStream([options])

作用

用于从文件中读取数据并生成一个可读流,这个方法允许你以流的方式读取文件,而不是一次性将整个文件读入内存。这种方式常用来处理大型文件,它可以减少内存占用并提高程序的效率。

该方法返回一个可读流实例,可以通过监听 dataerrorend 事件来处理流中的数据。

参数

  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • encoding(可选):string\color{green}string 用于指定文件读取时使用的字符编码。默认值为 null,表示数据以 Buffer 对象的形式返回。如果设置了特定的编码(例如 'utf8'、'ascii' 或 'base64' 等),则返回的数据将被解码为字符串。
    • autoClose(可选):boolean\color{green}boolean 表示当可读流的数据被完全消费后,是否自动关闭文件句柄。默认值为 true
    • emitClose(可选):boolean\color{green}boolean 用于指定当可读流关闭时,是否触发 close 事件。默认值为 true。可以监听 close 事件以在流关闭后执行额外的操作。
    • start(可选):integer\color{green}integer 表示从文件的哪个字节位置开始读取,默认值为 0。
    • end(可选):integer\color{green}integer 表示读取到文件的哪个字节位置为止,默认值为文件的最后一个字节。
    • highWaterMark(可选):integer\color{green}integer 表示每次从文件中读取的最大字节数量。当流的缓冲区达到这个值时,读取会暂停,直到缓冲区被消耗。默认值为 64KB。

示例


import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')
  const readStream = filehandle.createReadStream({ start: 0, end: 9 })

  readStream.on('data', chunk => {
    console.log(chunk.toString())
  })

  readStream.on('error', err => {
    console.error('读取错误:', err)
  })

  readStream.on('end', () => {
    console.log('读取完毕')
  })
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

7. filehandle.createWriteStream([options])

作用

用于创建可写流(writable stream)。它允许开发者以流的方式,将数据写入文件系统中的指定文件。

该方法返回一个可写流实例,可以使用 write()end() 方法向流中写入数据。

参数

  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • encoding(可选):string\color{green}string 指定写入数据时使用的字符编码,默认值为 'utf8'
    • autoClose(可选):boolean\color{green}boolean 表示在可写流结束或发生错误时是否自动关闭文件句柄,默认值为 true
    • emitClose(可选):boolean\color{green}boolean 用于指定当可写流关闭时,是否触发 close 事件,默认值为 true
    • start(可选):integer\color{green}integer 表示从文件的哪个字节位置开始读取,默认值为 0。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'w');
  const writeStream = filehandle.createWriteStream({ start: 0 });

  writeStream.write('Hello, world!\n');
  writeStream.write('This is an example.\n');
  writeStream.end('Goodbye, world!');

  writeStream.on('finish', () => {
    console.log('写入完毕');
  });

  writeStream.on('error', (err) => {
    console.error('写入出错:', err);
  });

  writeStream.on('close', () => {
    console.log('可写流关闭');
  });

} catch (err) {
  console.error('出错了:', err);
} finally {
  await filehandle?.close()
}

8. filehandle.datasync()

作用

用于将文件句柄(filehandle)所引用文件的数据同步到磁盘。

在写入文件时,操作系统通常会将数据缓存在内存中,然后在适当的时间将其写入磁盘。在某些情况下,我们可能需要确保数据立即写入磁盘,以减少数据丢失的风险。filehandle.datasync() 方法提供了这种功能。

对于大多数应用程序来说,并不需要手动调用 datasync() 方法。当使用 fs.writeFile()或 fs.createWriteStream() 等方法时,Node.js 会自动将数据缓冲区的修改同步到磁盘中,因此我们无需手动调用 datasync() 方法。

在某些情况下,你可能希望立即将数据写入磁盘,而不是依赖于操作系统自动完成这个操作。这可能是因为以下原因:

  1. 减少数据丢失风险: 在某些关键场景中,你可能希望确保数据立即写入磁盘,以防止意外情况(例如断电或系统崩溃)导致数据丢失。
  2. 提高可靠性: 在某些应用程序中,数据的可靠性至关重要。使用 filehandle.datasync() 可以确保数据在适当的时间点写入磁盘。
  3. 控制数据同步的时机: 在某些情况下,你可能希望控制数据同步到磁盘的时机,例如在执行多个写入操作后一次性将数据写入磁盘。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'a')
  const data = '用户支付完毕\n'

  await filehandle.write(data)
  await filehandle.datasync()

  console.log('数据已写入并同步到磁盘')
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

9. filehandle.fd

作用

这是一个属性,表示文件句柄对象的文件描述符。文件描述符(File Descriptor,简称 fd)是一个整数,由操作系统分配,用于标识特定的已打开文件。文件描述符在执行文件操作时起着关键作用,因为它们提供了访问打开文件的一种方式。

当使用 fsPromises.open() 或类似方法打开一个文件时,操作系统会返回一个文件句柄对象(FileHandle),其中包含与该文件关联的文件描述符。filehandle.fd 属性提供了访问这个文件描述符的途径。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')
  const fd = filehandle.fd

  console.log(`文件描述符:${fd}`)
} catch (err) {
  console.error('Error:', err)
} finally {
  await filehandle?.close()
}

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

作用

用于从指定位置读取数据到缓冲区(buffer)中。这个方法可以从一个已打开的文件句柄(filehandle)中读取数据,并将数据存储在指定的 buffer 中。

成功时返回一个具有两个属性的对象:

  • bytesRead:读取的字节数。
  • buffer: 存储在缓冲区中的数据内容。如果指定了 options.buffer,则直接返回该缓冲区;否则将创建新的 Buffer 对象。

参数

  • bufferBufferTypedArrayDataView\color{green}Buffer | TypedArray | DataView 表示数据将被写入的缓冲区
  • offsetinteger\color{green}integer 表示在 buffer 中存储数据的起始位置
  • lengthinteger\color{green}integer 表示要读取的字节数。当文件字节数小于这个值时,它将被设置为文件字节数。
  • positionintegernull\color{green}integer | null 表示文件中开始读取的位置。如果设置为 null,则从文件的当前位置开始读取。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')

  // 创建一个大小为 1024 字节的 Buffer 对象
  const buffer = Buffer.alloc(1024)

  // 从 filehandle 文件句柄读取数据,将其存储到 buffer 对象中
  const { bytesRead } = await filehandle.read(buffer, 0, buffer.length, null)

  console.log('从文件中读取的字节数:', bytesRead)
  console.log('内容为:', buffer.subarray(0, bytesRead).toString())
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

11. filehandle.read([options])

作用

用于从指定位置读取数据到缓冲区(buffer)中。与 filehandle.read(buffer, offset, length, position) 一致,主要区别在于参数传递方式不同,它不需要传入4个参数,只接受一个可选的 options 对象作为参数,只设置需要的选项,未设置的选项将使用默认值,可以更灵活地控制读取操作。

成功时返回一个具有两个属性的对象:

  • bytesRead:读取的字节数。
  • buffer: 存储在缓冲区中的数据内容。如果指定了 options.buffer,则直接返回该缓冲区;否则将创建新的 Buffer 对象。

参数

  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • buffer(可选):BufferTypedArrayDataView\color{green}Buffer | TypedArray | DataView 表示数据将被写入的缓冲区,默认值:Buffer.alloc(16384)
    • offset(可选):integer\color{green}integer 表示在 buffer 中存储数据的起始位置,默认值:0
    • length(可选):integer\color{green}integer 表示要读取的字节数。当文件字节数小于这个值时,它将被设置为文件字节数,默认值:buffer.byteLength - offset
    • position(可选):integernull\color{green}integer | null 表示文件中开始读取的位置。如果设置为 null,则从文件的当前位置开始读取,默认值:null

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')

  // 创建一个大小为 1024 字节的 Buffer 对象
  const buffer = Buffer.alloc(1024)
  const options = {
    buffer,
    offset: 0,
    length: buffer.length,
    position: null
  }

  // 从 filehandle 文件句柄读取数据,将其存储到 buffer 对象中
  const { bytesRead } = await filehandle.read(options)

  console.log('从文件中读取的字节数:', bytesRead)
  console.log('内容为:', buffer.subarray(0, bytesRead).toString())

} catch (err) {
  console.error('Error:', err)
} finally {
  await filehandle?.close()
}

12. filehandle.read(buffer[, options])

作用

用于从指定位置读取数据到缓冲区(buffer)中。

成功时返回一个包含两个属性的对象:

  • bytesRead: 整数,表示实际读取的字节数
  • buffer: 表示文件内容的缓冲区

参数

  • buffer: BufferTypedArrayDataView\color{green}Buffer | TypedArray | DataView 表示从文件读取的数据将会写入到这个缓冲区。
  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • offset(可选):integer\color{green}integer 表示在 buffer 中存储数据的起始位置,默认值:0
    • length(可选):integer\color{green}integer 表示要读取的字节数。当文件字节数小于这个值时,它将被设置为文件字节数,默认值:buffer.byteLength - offset
    • position(可选):integernull\color{green}integer | null 表示文件中开始读取的位置。如果设置为 null,则从文件的当前位置开始读取,默认值:null

示例

import * as fsPromises from 'node:fs/promises'

// 创建一个缓冲区,并打开文件以进行读取操作
const buf = Buffer.alloc(100)
const fileHandle = await fsPromises.open('./fs/heihei.txt', 'r')

try {
  // 从文件中读取数据到缓冲区
  const { bytesRead, buffer } = await fileHandle.read(buf, 0, 100, null)

  // 打印读取的字节数和读取的数据
  console.log(`${bytesRead} 字节被读取`)
  console.log(buffer.toString())
} finally {
  // 关闭文件句柄
  await fileHandle.close()
}

13.filehandle.readFile(options)

作用

用于从已打开的文件句柄(FileHandle)中异步读取整个文件内容

参数

  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • encoding(可选):stringnull\color{green}string | null 指定文件内容的字符编码。如果提供了该选项,那么返回的数据将是一个解码后的字符串,而不是一个 Buffer。默认情况下,该值为 null,表示返回原始的 Buffer 数据。
    • signal(可选):AbortSignal\color{green}AbortSignal 用于中止读取操作。如果传递了已中止的信号,那么 readFile 方法将抛出 AbortError。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')

  const content = await filehandle.readFile({ encoding: 'utf8' })

  console.log('文件内容:', content)

} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

14. filehandle.readLines([options])

如果你的node版本低于18.11.0,不支持此方法\color{red}如果你的 node 版本低于 18.11.0,不支持此方法

作用

用于从已打开的文件句柄(FileHandle)中异步按行读取文件内容

参数

  • options(可选):<Object\color{green}Object 配置对象,包含以下可选属性:
    • encoding(可选):string\color{green}string 指定读取文件时使用的字符编码,默认值为 null,表示数据以 Buffer 对象的形式返回。如果设置了特定的编码(例如 'utf8'、'ascii' 或 'base64' 等),则返回的数据将被解码为字符串。
    • autoClose(可选):boolean\color{green}boolean 表示当可读流的数据被完全消费后,是否自动关闭文件句柄。默认值为 true
    • emitClose(可选):boolean\color{green}boolean 用于指定当可读流关闭时,是否触发 close 事件。默认值为 true。可以监听 close 事件以在流关闭后执行额外的操作。
    • start(可选):integer\color{green}integer 表示从文件的哪个字节位置开始读取,默认值为 0。
    • end(可选):integer\color{green}integer 表示读取到文件的哪个字节位置为止,默认值为文件的最后一个字节。
    • highWaterMark(可选):integer\color{green}integer 表示每次从文件中读取的最大字节数量,默认值为 64KB。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')

  // 使用 readLines 方法逐行读取文件的内容
  const content = await filehandle.readLines({ encoding: 'utf8' })

  // 遍历所有的行,将每一行打印到控制台
  for await (const line of content) {
    console.log(line)
  }

} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

15. filehandle.readv(buffers[, position])

作用

用于从已打开的文件句柄(FileHandle)中异步读取数据,其特点是可以将读取的数据直接存储到一个 Buffer 数组中(称为“scatter read”)。

成功时返回一个包含两个属性的对象:

  • bytesRead:读取到的字节数。
  • buffers:传入的 buffers 参数中每个 Buffer 实例所包含的已读取的数据。

参数

  • buffersBuffer[]TypedArray[]DataView[]\color{green}Buffer[] | TypedArray[] | DataView[] 一个包含多个 Buffer 实例的数组或者是一个 TypedArray 数组。方法将按照数组中的顺序将从文件中读取的数据填充到这些 Buffer 中。
  • position(可选):integernull\color{green}integer | null 表示从文件中读取数据的起始位置。如果设置为 null 或省略,将从文件的当前位置开始读取,默认值为 null

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')

  const buffers = [Buffer.alloc(5), Buffer.alloc(5)]
  const { bytesRead } = await filehandle.readv(buffers, 0)

  console.log(`${bytesRead} 字节被读取`)

  for (const [index, buffer] of buffers.entries()) {
    console.log(`Buffer ${index + 1}:`, buffer.subarray(0, bytesRead).toString())
  }

} catch (err) {
  console.error('Error:', err)
} finally {
  await filehandle?.close()
}

16. filehandle.stat([options])

作用

用于获取已打开文件句柄(filehandle)关联文件的元数据信息(如大小、修改时间等)

参数

  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • bigint(可选):boolean\color{green}boolean 默认值为 false,设置为 true 时,返回的文件大小(size)和 inode 的值将以 BigInt 类型返回,以防止数值过大而出现精度损失。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r')

  const stats = await filehandle.stat({ bigint: false })

  console.log('文件元信息:', stats)
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

/*
控制台输出结果
文件元信息:Stats {
  dev: 16777221,
  mode: 33188,
  nlink: 1,
  uid: 501,
  gid: 20,
  rdev: 0,
  blksize: 4096,
  ino: 102503788,
  size: 12,
  blocks: 8,
  atimeMs: 1683352522560.0571,
  mtimeMs: 1683352520654.094,
  ctimeMs: 1683352520654.094,
  birthtimeMs: 1683110628364.2732,
  atime: 2023-05-06T05:55:22.560Z,
  mtime: 2023-05-06T05:55:20.654Z,
  ctime: 2023-05-06T05:55:20.654Z,
  birthtime: 2023-05-03T10:43:48.364Z
}
*/

17. filehandle.sync()

作用

该方法为同步方法,用于异步将文件句柄(FileHandle)关联的文件的所有修改操作同步到底层文件系统,换句话说,将文件缓存区中的数据立即写入磁盘中。

在实际应用程序中,无需在每次写入操作后都手动调用 sync() 方法,因为 Node.js 文件系统会自动周期性地清空缓存并将所有未同步操作写入到磁盘上。

这是一个阻塞函数,它会一直等待,直到所有未同步的数据都被写入到磁盘为止。因此,在频繁写入大量数据的情况下,建议不要过度使用 sync() 方法,以避免影响应用程序的性能。

使用 filehandle.sync() 时需要保证 FileHandle 实例是以可写、追加或读写模式打开的。如果使用只读模式或没有打开文件,则会抛出错误。

这个方法在以下场景中可能会有用:

  1. 在执行一系列文件修改操作后,确保所有更改已经持久化到磁盘,以防止数据丢失;
  2. 在执行关键任务之前确保文件状态与内存中的缓冲区同步,以确保数据的一致性。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'w')

  filehandle.write('瓶子')
  filehandle.sync()
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

18. filehandle.truncate(len)

作用

用于截断(truncate)已打开文件句柄(filehandle)关联文件的方法。截断意味着更改文件的大小,你可以通过此方法将文件缩短为指定的长度。

参数

  • leninteger\color{green}integer 文件截断后应该具有的长度(单位:字节)。如果当前文件比 len 长,则超出部分将被截断;如果当前文件比 len 短,则其内容将不受影响,但文件大小将被设置为 len。

注意⚠:len 必须大于或等于 0。如果 len 被设置为 0,则该文件将被清空(即变为空文件)。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'w+')

  await filehandle.truncate(7) // 截取文件到7字节
  console.log('文件已截取')
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

19. filehandle.utimes(atime, mtime)

作用

用于改变文件的访问时间(atime)和修改时间(mtime)

参数

  • atimenumberstringDate\color{green}number | string | Date 要设置的访问时间(access time),表示文件最后一次被访问(读取、写入等操作)的时间。
  • mtimenumberstringDate\color{green}number | string | Date 要设置的修改时间(modification time),表示文件最后一次被修改(内容更改)的时间。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r+')

  const newAtime = new Date('2023-05-06 15:46:00')
  const newMtime = new Date('2023-05-04 19:44:25')

  await filehandle.utimes(newAtime, newMtime)
  console.log('文件访问和修改时间已更新')
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

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

作用

用于向文件中写入数据,即将指定缓冲区(buffer)的数据异步写入已打开的文件句柄(filehandle)关联的文件

参数

  • buffer: BufferTypedArrayDataView\color{green}Buffer | TypedArray | DataView 表示要写入文件的数据。
  • offsetinteger\color{green}integer 表示从缓冲区的哪个位置开始读取数据。
  • length(可选):integer\color{green}integer 表示要写入的字节数。如果省略此参数,则默认为 buffer.length - offset
  • position(可选):integernull\color{green}integer | null 表示从文件的哪个位置开始写入数据。如果省略此参数,则从当前文件指针的位置开始写入数据。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r+')

  const buffer = Buffer.from('Hello, World!', 'utf-8')
  const offset = 7
  const length = 5
  const position = 6

  const { bytesWritten } = await filehandle.write(buffer, offset, length, position)

  console.log(`${bytesWritten} 字节被读取`)
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

21.filehandle.write(buffer[, options])

作用

用于将指定的 buffer 内容写入到文件中。

参数

  • buffer: BufferTypedArrayDataView\color{green}Buffer | TypedArray | DataView 表示要写入文件的数据。
  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • offsetinteger\color{green}integer 表示从缓冲区的哪个位置开始读取数据,默认为0
    • length(可选):integer\color{green}integer 表示要写入的字节数。如果省略此参数,则默认为 buffer.length - offset
    • position(可选):integernull\color{green}integer | null 表示从文件的哪个位置开始写入数据。如果省略此参数,则默认为null,从当前文件指针的位置开始写入数据。默认为null

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r+')

  const buffer = Buffer.from('Hello, Node.js!', 'utf-8')
  const options = {
    offset: 7,
    length: 7,
    position: 6
  }

  const { bytesWritten } = await filehandle.write(buffer, options)

  console.log(`${bytesWritten} 字节被读取`)
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

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

作用

用于向指定文件中写入字符串数据。

参数

  • stringstring\color{green}string 要写入文件的数据
  • position(可选):integer\color{green}integer 表示从文件的哪个位置开始写入数据。默认值为 null,表示从文件的当前位置开始写入。
  • encoding(可选):string\color{green}string 表示用于编码字符串的字符编码。默认值为 'utf8'。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'r+')

  const { bytesWritten } = await filehandle.write('Hi Node.js!', null, 'utf-8');

  console.log(`${bytesWritten} 字节被读取`)
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

23. filehandle.writeFile(data, options)

作用

用于向已打开的文件中写入数据,该方法会覆盖目标文件的内容,而非插入到指定位置。

参数

  • datastringBufferTypedArrayDataViewAsyncIterableIterableStream\color{green}string | Buffer | TypedArray | DataView | AsyncIterable | Iterable | Stream 要写入文件的数据。
  • options(可选):Object\color{green}Object 配置对象,包含以下可选属性:
    • encoding(可选):stringnull\color{green}string | null 表示用于编码字符串的字符编码。当 data 为字符串时,默认值为 'utf8'。当 data 为 Buffer 或 Uint8Array 时,该选项会被忽略。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'w')

  const data = '文件系统'
  const options = {
    encoding: 'utf8'
  }

  await filehandle.writeFile(data, options)
  console.log('文件已写入')
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}

24. filehandle.writev(buffers[, position])

作用

用于向已打开的文件中写入数据块。与 filehandle.write() 方法不同的是,该方法支持一次性写入多个数据块,效率更高。

参数

  • buffersBuffer[]TypedArray[]DataView[]\color{green}Buffer[] | TypedArray[] | DataView[] 要写入的数据块数组。
  • position(可选):integernull\color{green}integer | null 表示从文件的哪个位置开始写入数据。默认值为 null,表示从文件的当前位置开始写入。

示例

import * as fsPromises from 'node:fs/promises'

let filehandle

try {
  filehandle = await fsPromises.open('./fs/heihei.txt', 'w')

  const buffers = [
    Buffer.from('Hello, ', 'utf-8'),
    Buffer.from('Node.js!', 'utf-8')
  ]

  const { bytesWritten, buffers: writtenBuffers } = await filehandle.writev(buffers, null)

  console.log(`${bytesWritten} 字节被写入`)
  console.log('写入内容:', writtenBuffers.join('').toString())
} catch (err) {
  console.error('出错了:', err)
} finally {
  await filehandle?.close()
}