- assert断言
- async_hooks异步钩子
- async_hooks/context异步上下文
- buffer缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process子进程
- cluster集群
- CLI命令行
- console控制台
- Corepack核心包
- crypto加密
- crypto/webcrypto网络加密
- debugger调试器
- deprecation弃用
- dgram数据报
- diagnostics_channel诊断通道
- dns域名服务器
- domain域
- Error错误
- events事件触发器
- fs文件系统
- global全局变量
- http超文本传输协议
- http2超文本传输协议2.0
- https安全超文本传输协议
- inspector检查器
- Intl国际化
- module模块
- module/cjsCommonJS模块
- module/esmECMAScript模块
- module/package包模块
- net网络
- os操作系统
- path路径
- perf_hooks性能钩子
- permission权限
- policy安全策略
- process进程
- punycode域名代码
- querystring查询字符串
- readline逐行读取
- repl交互式解释器
- report诊断报告
- stream流
- stream/web网络流
- string_decoder字符串解码器
- test测试
- timers定时器
- tls安全传输层
- trace_events跟踪事件
- tty终端
- url网址
- util实用工具
- v8引擎
- vm虚拟机
- wasi网络汇编系统接口
- worker_threads工作线程
- zlib压缩
Node.js v16.19.1 文档
- Node.js 16.19.1
-
►
目录
- fs 文件系统
- Promise 的示例
- 回调的示例
- 同步的示例
- Promise 的 API
FileHandle
类'close'
事件filehandle.appendFile(data[, options])
filehandle.chmod(mode)
filehandle.chown(uid, gid)
filehandle.close()
filehandle.createReadStream([options])
filehandle.createWriteStream([options])
filehandle.datasync()
filehandle.fd
filehandle.read(buffer, offset, length, position)
filehandle.read([options])
filehandle.read(buffer[, options])
filehandle.readFile(options)
filehandle.readv(buffers[, position])
filehandle.stat([options])
filehandle.sync()
filehandle.truncate(len)
filehandle.utimes(atime, mtime)
filehandle.write(buffer, offset[, length[, position]])
filehandle.write(buffer[, options])
filehandle.write(string[, position[, encoding]])
filehandle.writeFile(data, options)
filehandle.writev(buffers[, position])
fsPromises.access(path[, mode])
fsPromises.appendFile(path, data[, options])
fsPromises.chmod(path, mode)
fsPromises.chown(path, uid, gid)
fsPromises.copyFile(src, dest[, mode])
fsPromises.cp(src, dest[, options])
fsPromises.lchmod(path, mode)
fsPromises.lchown(path, uid, gid)
fsPromises.lutimes(path, atime, mtime)
fsPromises.link(existingPath, newPath)
fsPromises.lstat(path[, options])
fsPromises.mkdir(path[, options])
fsPromises.mkdtemp(prefix[, options])
fsPromises.open(path, flags[, mode])
fsPromises.opendir(path[, options])
fsPromises.readdir(path[, options])
fsPromises.readFile(path[, options])
fsPromises.readlink(path[, options])
fsPromises.realpath(path[, options])
fsPromises.rename(oldPath, newPath)
fsPromises.rmdir(path[, options])
fsPromises.rm(path[, options])
fsPromises.stat(path[, options])
fsPromises.symlink(target, path[, type])
fsPromises.truncate(path[, len])
fsPromises.unlink(path)
fsPromises.utimes(path, atime, mtime)
fsPromises.watch(filename[, options])
fsPromises.writeFile(file, data[, options])
fsPromises.constants
- 回调的 API
fs.access(path[, mode], callback)
fs.appendFile(path, data[, options], callback)
fs.chmod(path, mode, callback)
fs.chown(path, uid, gid, callback)
fs.close(fd[, callback])
fs.copyFile(src, dest[, mode], callback)
fs.cp(src, dest[, options], callback)
fs.createReadStream(path[, options])
fs.createWriteStream(path[, options])
fs.exists(path, callback)
fs.fchmod(fd, mode, callback)
fs.fchown(fd, uid, gid, callback)
fs.fdatasync(fd, callback)
fs.fstat(fd[, options], callback)
fs.fsync(fd, callback)
fs.ftruncate(fd[, len], callback)
fs.futimes(fd, atime, mtime, callback)
fs.lchmod(path, mode, callback)
fs.lchown(path, uid, gid, callback)
fs.lutimes(path, atime, mtime, callback)
fs.link(existingPath, newPath, callback)
fs.lstat(path[, options], callback)
fs.mkdir(path[, options], callback)
fs.mkdtemp(prefix[, options], callback)
fs.open(path[, flags[, mode]], callback)
fs.opendir(path[, options], callback)
fs.read(fd, buffer, offset, length, position, callback)
fs.read(fd[, options], callback)
fs.read(fd, buffer[, options], callback)
fs.readdir(path[, options], callback)
fs.readFile(path[, options], callback)
fs.readlink(path[, options], callback)
fs.readv(fd, buffers[, position], callback)
fs.realpath(path[, options], callback)
fs.realpath.native(path[, options], callback)
fs.rename(oldPath, newPath, callback)
fs.rmdir(path[, options], callback)
fs.rm(path[, options], callback)
fs.stat(path[, options], callback)
fs.symlink(target, path[, type], callback)
fs.truncate(path[, len], callback)
fs.unlink(path, callback)
fs.unwatchFile(filename[, listener])
fs.utimes(path, atime, mtime, callback)
fs.watch(filename[, options][, listener])
fs.watchFile(filename[, options], listener)
fs.write(fd, buffer, offset[, length[, position]], callback)
fs.write(fd, buffer[, options], callback)
fs.write(fd, string[, position[, encoding]], callback)
fs.writeFile(file, data[, options], callback)
fs.writev(fd, buffers[, position], callback)
- 同步的 API
fs.accessSync(path[, mode])
fs.appendFileSync(path, data[, options])
fs.chmodSync(path, mode)
fs.chownSync(path, uid, gid)
fs.closeSync(fd)
fs.copyFileSync(src, dest[, mode])
fs.cpSync(src, dest[, options])
fs.existsSync(path)
fs.fchmodSync(fd, mode)
fs.fchownSync(fd, uid, gid)
fs.fdatasyncSync(fd)
fs.fstatSync(fd[, options])
fs.fsyncSync(fd)
fs.ftruncateSync(fd[, len])
fs.futimesSync(fd, atime, mtime)
fs.lchmodSync(path, mode)
fs.lchownSync(path, uid, gid)
fs.lutimesSync(path, atime, mtime)
fs.linkSync(existingPath, newPath)
fs.lstatSync(path[, options])
fs.mkdirSync(path[, options])
fs.mkdtempSync(prefix[, options])
fs.opendirSync(path[, options])
fs.openSync(path[, flags[, mode]])
fs.readdirSync(path[, options])
fs.readFileSync(path[, options])
fs.readlinkSync(path[, options])
fs.readSync(fd, buffer, offset, length[, position])
fs.readSync(fd, buffer[, options])
fs.readvSync(fd, buffers[, position])
fs.realpathSync(path[, options])
fs.realpathSync.native(path[, options])
fs.renameSync(oldPath, newPath)
fs.rmdirSync(path[, options])
fs.rmSync(path[, options])
fs.statSync(path[, options])
fs.symlinkSync(target, path[, type])
fs.truncateSync(path[, len])
fs.unlinkSync(path)
fs.utimesSync(path, atime, mtime)
fs.writeFileSync(file, data[, options])
fs.writeSync(fd, buffer, offset[, length[, position]])
fs.writeSync(fd, buffer[, options])
fs.writeSync(fd, string[, position[, encoding]])
fs.writevSync(fd, buffers[, position])
- 公共对象
fs.Dir
类fs.Dirent
类fs.FSWatcher
类fs.StatWatcher
类fs.ReadStream
类fs.Stats
类stats.isBlockDevice()
stats.isCharacterDevice()
stats.isDirectory()
stats.isFIFO()
stats.isFile()
stats.isSocket()
stats.isSymbolicLink()
stats.dev
stats.ino
stats.mode
stats.nlink
stats.uid
stats.gid
stats.rdev
stats.size
stats.blksize
stats.blocks
stats.atimeMs
stats.mtimeMs
stats.ctimeMs
stats.birthtimeMs
stats.atimeNs
stats.mtimeNs
stats.ctimeNs
stats.birthtimeNs
stats.atime
stats.mtime
stats.ctime
stats.birthtime
- 统计的时间值
fs.WriteStream
类fs.constants
- 注意事项
- fs 文件系统
-
►
索引
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS模块
- module/esm ECMAScript模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- policy 安全策略
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- ► 其他版本
- 文档搜索
目录
- fs 文件系统
- Promise 的示例
- 回调的示例
- 同步的示例
- Promise 的 API
FileHandle
类'close'
事件filehandle.appendFile(data[, options])
filehandle.chmod(mode)
filehandle.chown(uid, gid)
filehandle.close()
filehandle.createReadStream([options])
filehandle.createWriteStream([options])
filehandle.datasync()
filehandle.fd
filehandle.read(buffer, offset, length, position)
filehandle.read([options])
filehandle.read(buffer[, options])
filehandle.readFile(options)
filehandle.readv(buffers[, position])
filehandle.stat([options])
filehandle.sync()
filehandle.truncate(len)
filehandle.utimes(atime, mtime)
filehandle.write(buffer, offset[, length[, position]])
filehandle.write(buffer[, options])
filehandle.write(string[, position[, encoding]])
filehandle.writeFile(data, options)
filehandle.writev(buffers[, position])
fsPromises.access(path[, mode])
fsPromises.appendFile(path, data[, options])
fsPromises.chmod(path, mode)
fsPromises.chown(path, uid, gid)
fsPromises.copyFile(src, dest[, mode])
fsPromises.cp(src, dest[, options])
fsPromises.lchmod(path, mode)
fsPromises.lchown(path, uid, gid)
fsPromises.lutimes(path, atime, mtime)
fsPromises.link(existingPath, newPath)
fsPromises.lstat(path[, options])
fsPromises.mkdir(path[, options])
fsPromises.mkdtemp(prefix[, options])
fsPromises.open(path, flags[, mode])
fsPromises.opendir(path[, options])
fsPromises.readdir(path[, options])
fsPromises.readFile(path[, options])
fsPromises.readlink(path[, options])
fsPromises.realpath(path[, options])
fsPromises.rename(oldPath, newPath)
fsPromises.rmdir(path[, options])
fsPromises.rm(path[, options])
fsPromises.stat(path[, options])
fsPromises.symlink(target, path[, type])
fsPromises.truncate(path[, len])
fsPromises.unlink(path)
fsPromises.utimes(path, atime, mtime)
fsPromises.watch(filename[, options])
fsPromises.writeFile(file, data[, options])
fsPromises.constants
- 回调的 API
fs.access(path[, mode], callback)
fs.appendFile(path, data[, options], callback)
fs.chmod(path, mode, callback)
fs.chown(path, uid, gid, callback)
fs.close(fd[, callback])
fs.copyFile(src, dest[, mode], callback)
fs.cp(src, dest[, options], callback)
fs.createReadStream(path[, options])
fs.createWriteStream(path[, options])
fs.exists(path, callback)
fs.fchmod(fd, mode, callback)
fs.fchown(fd, uid, gid, callback)
fs.fdatasync(fd, callback)
fs.fstat(fd[, options], callback)
fs.fsync(fd, callback)
fs.ftruncate(fd[, len], callback)
fs.futimes(fd, atime, mtime, callback)
fs.lchmod(path, mode, callback)
fs.lchown(path, uid, gid, callback)
fs.lutimes(path, atime, mtime, callback)
fs.link(existingPath, newPath, callback)
fs.lstat(path[, options], callback)
fs.mkdir(path[, options], callback)
fs.mkdtemp(prefix[, options], callback)
fs.open(path[, flags[, mode]], callback)
fs.opendir(path[, options], callback)
fs.read(fd, buffer, offset, length, position, callback)
fs.read(fd[, options], callback)
fs.read(fd, buffer[, options], callback)
fs.readdir(path[, options], callback)
fs.readFile(path[, options], callback)
fs.readlink(path[, options], callback)
fs.readv(fd, buffers[, position], callback)
fs.realpath(path[, options], callback)
fs.realpath.native(path[, options], callback)
fs.rename(oldPath, newPath, callback)
fs.rmdir(path[, options], callback)
fs.rm(path[, options], callback)
fs.stat(path[, options], callback)
fs.symlink(target, path[, type], callback)
fs.truncate(path[, len], callback)
fs.unlink(path, callback)
fs.unwatchFile(filename[, listener])
fs.utimes(path, atime, mtime, callback)
fs.watch(filename[, options][, listener])
fs.watchFile(filename[, options], listener)
fs.write(fd, buffer, offset[, length[, position]], callback)
fs.write(fd, buffer[, options], callback)
fs.write(fd, string[, position[, encoding]], callback)
fs.writeFile(file, data[, options], callback)
fs.writev(fd, buffers[, position], callback)
- 同步的 API
fs.accessSync(path[, mode])
fs.appendFileSync(path, data[, options])
fs.chmodSync(path, mode)
fs.chownSync(path, uid, gid)
fs.closeSync(fd)
fs.copyFileSync(src, dest[, mode])
fs.cpSync(src, dest[, options])
fs.existsSync(path)
fs.fchmodSync(fd, mode)
fs.fchownSync(fd, uid, gid)
fs.fdatasyncSync(fd)
fs.fstatSync(fd[, options])
fs.fsyncSync(fd)
fs.ftruncateSync(fd[, len])
fs.futimesSync(fd, atime, mtime)
fs.lchmodSync(path, mode)
fs.lchownSync(path, uid, gid)
fs.lutimesSync(path, atime, mtime)
fs.linkSync(existingPath, newPath)
fs.lstatSync(path[, options])
fs.mkdirSync(path[, options])
fs.mkdtempSync(prefix[, options])
fs.opendirSync(path[, options])
fs.openSync(path[, flags[, mode]])
fs.readdirSync(path[, options])
fs.readFileSync(path[, options])
fs.readlinkSync(path[, options])
fs.readSync(fd, buffer, offset, length[, position])
fs.readSync(fd, buffer[, options])
fs.readvSync(fd, buffers[, position])
fs.realpathSync(path[, options])
fs.realpathSync.native(path[, options])
fs.renameSync(oldPath, newPath)
fs.rmdirSync(path[, options])
fs.rmSync(path[, options])
fs.statSync(path[, options])
fs.symlinkSync(target, path[, type])
fs.truncateSync(path[, len])
fs.unlinkSync(path)
fs.utimesSync(path, atime, mtime)
fs.writeFileSync(file, data[, options])
fs.writeSync(fd, buffer, offset[, length[, position]])
fs.writeSync(fd, buffer[, options])
fs.writeSync(fd, string[, position[, encoding]])
fs.writevSync(fd, buffers[, position])
- 公共对象
fs.Dir
类fs.Dirent
类fs.FSWatcher
类fs.StatWatcher
类fs.ReadStream
类fs.Stats
类stats.isBlockDevice()
stats.isCharacterDevice()
stats.isDirectory()
stats.isFIFO()
stats.isFile()
stats.isSocket()
stats.isSymbolicLink()
stats.dev
stats.ino
stats.mode
stats.nlink
stats.uid
stats.gid
stats.rdev
stats.size
stats.blksize
stats.blocks
stats.atimeMs
stats.mtimeMs
stats.ctimeMs
stats.birthtimeMs
stats.atimeNs
stats.mtimeNs
stats.ctimeNs
stats.birthtimeNs
stats.atime
stats.mtime
stats.ctime
stats.birthtime
- 统计的时间值
fs.WriteStream
类fs.constants
- 注意事项
fs 文件系统#
源代码: lib/fs.js
node:fs
模块能够以标准 POSIX 函数为模型的方式与文件系统进行交互。
要使用基于 promise 的 API:
import * as fs from 'node:fs/promises';
const fs = require('node:fs/promises');
要使用回调和同步的 API:
import * as fs from 'node:fs';
const fs = require('node:fs');
所有文件系统操作都具有同步、回调和基于 promise 的形式,并且可以使用 CommonJS 语法和 ES6 模块进行访问。
Promise 的示例#
基于 promise 的操作会返回一个当异步操作完成时被履行的 promise。
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);
}
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');
回调的示例#
回调的形式将完成回调函数作为其最后一个参数并且异步地调用该操作。
传给完成回调的参数取决于方法,但是第一个参数始终预留用于异常。
如果操作成功地完成,则第一个参数为 null
或 undefined
。
import { unlink } from 'node:fs';
unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
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
来处理,也可以允许冒泡。
import { unlinkSync } from 'node:fs';
try {
unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (err) {
// 处理错误
}
const { unlinkSync } = require('node:fs');
try {
unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (err) {
// 处理错误
}
Promise 的 API#
该 fs/promises
API 提供了返回 promise 的异步的文件系统方法。
Promise API 使用底层的 Node.js 线程池在事件循环线程之外执行文件系统操作。 这些操作不是同步的也不是线程安全的。 对同一文件执行多个并发修改时必须小心,否则可能会损坏数据。
FileHandle
类#
<FileHandle> 对象是数字文件描述符的对象封装。
<FileHandle> 对象的实例通过 fsPromises.open()
方法创建。
所有 <FileHandle> 对象都是 <EventEmitter>。
如果未使用 filehandle.close()
方法关闭 <FileHandle>,则它将尝试自动关闭文件描述符并触发进程警告,从而有助于防止内存泄漏。
请不要依赖此行为,因为它可能不可靠并且该文件可能未被关闭。
而是,始终显式关闭 <FileHandle>。
Node.js 将来可能会更改此行为。
'close'
事件#
当 <FileHandle> 已关闭且不再可用时,则触发 'close'
事件。
filehandle.appendFile(data[, options])
#
data
<string> | <Buffer> | <TypedArray> | <DataView> | <AsyncIterable> | <Iterable> | <Stream>options
<Object> | <string>- 返回: <Promise> 成功时将使用
undefined
履行。
当在文件句柄上进行操作时,则无法将模式更改为使用 fsPromises.open()
设置的模式。
因此,这相当于 filehandle.writeFile()
。
filehandle.chmod(mode)
#
修改文件的权限。
参见 chmod(2)
。
filehandle.chown(uid, gid)
#
更改文件的所有权。
chown(2)
的封装。
filehandle.close()
#
- 返回: <Promise> 成功时将使用
undefined
履行。
等待句柄上的任何未决操作完成后,关闭文件句柄。
import { open } from 'node:fs/promises';
let filehandle;
try {
filehandle = await open('thefile.txt', 'r');
} finally {
await filehandle?.close();
}
filehandle.createReadStream([options])
#
options
<Object>- 返回: <fs.ReadStream>
与 <stream.Readable> 的 16 KiB 默认 highWaterMark
不同,此方法返回的流的默认 highWaterMark
为 64 KiB。
options
可以包括 start
和 end
值,以从文件中读取一定范围的字节,而不是整个文件。
start
和 end
都包含在内并且从 0 开始计数,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 范围内。
如果省略 start
或为 undefined
,则 filehandle.createReadStream()
从当前的文件位置开始依次读取。
encoding
可以是 <Buffer> 接受的任何一种。
如果 FileHandle
指向只支持阻塞读取的字符设备(如键盘或声卡),则读取操作在数据可用之前不会完成。
这可以防止进程退出和流自然关闭。
默认情况下,流将在销毁后触发 'close'
事件。
将 emitClose
选项设置为 false
以更改此行为。
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 个字节的示例:
import { open } from 'node:fs/promises';
const fd = await open('sample.txt');
fd.createReadStream({ start: 90, end: 99 });
filehandle.createWriteStream([options])
#
options
<Object>- 返回: <fs.WriteStream>
options
还可以包括 start
选项,以允许在文件开头的某个位置写入数据,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 范围内。
修改文件(而不是替换它)可能需要将 flags
open
选项设置为 r+
(而不是默认的 r
)。
encoding
可以是 <Buffer> 接受的任何一种。
如果将 autoClose
设置为 true(默认行为),则在 'error'
或 'finish'
时文件描述符将自动关闭。
如果 autoClose
为 false,则即使出现错误,文件描述符也不会关闭。
关闭它并确保没有文件描述符泄漏是应用程序的责任。
默认情况下,流将在销毁后触发 'close'
事件。
将 emitClose
选项设置为 false
以更改此行为。
filehandle.datasync()
#
- 返回: <Promise> 成功时将使用
undefined
履行。
将与文件关联的所有当前排队的 I/O 操作强制为操作系统的同步 I/O 完成状态。
有关详细信息,请参阅 POSIX fdatasync(2)
文档。
与 filehandle.sync
不同,此方法不会刷新修改的元数据。
filehandle.fd
#
- <number> 由 <FileHandle> 对象管理的数字文件描述符。
filehandle.read(buffer, offset, length, position)
#
buffer
<Buffer> | <TypedArray> | <DataView> 将填充读取的文件数据的缓冲区。offset
<integer> 缓冲区中开始填充的位置。length
<integer> 读取的字节数。position
<integer> | <null> 从文件开始读取数据的位置。 如果为null
,则将从当前文件位置读取数据,并将更新该位置。 如果position
是整数,则当前文件位置将保持不变。- 返回: <Promise> 成功时将使用具有以下两个属性的对象履行:
bytesRead
<integer> 读取的字节数buffer
<Buffer> | <TypedArray> | <DataView> 对传入的buffer
参数的引用。
从文件中读取数据,并将其存储在给定的缓冲区中。
如果未同时修改文件,当读取的字节数为零时,则到达文件末尾。
filehandle.read([options])
#
options
<Object>buffer
<Buffer> | <TypedArray> | <DataView> 将填充读取的文件数据的缓冲区。 默认值:Buffer.alloc(16384)
offset
<integer> 缓冲区中开始填充的位置。 默认值:0
length
<integer> 读取的字节数。 默认值:buffer.byteLength - offset
position
<integer> | <null> 从文件开始读取数据的位置。 如果为null
,则将从当前文件位置读取数据,并将更新该位置。 如果position
是整数,则当前文件位置将保持不变。 默认值::null
- 返回: <Promise> 成功时将使用具有以下两个属性的对象履行:
bytesRead
<integer> 读取的字节数buffer
<Buffer> | <TypedArray> | <DataView> 对传入的buffer
参数的引用。
从文件中读取数据,并将其存储在给定的缓冲区中。
如果未同时修改文件,当读取的字节数为零时,则到达文件末尾。
filehandle.read(buffer[, options])
#
buffer
<Buffer> | <TypedArray> | <DataView> 将填充读取的文件数据的缓冲区。options
<Object>- 返回: <Promise> 成功时将使用具有以下两个属性的对象履行:
bytesRead
<integer> 读取的字节数buffer
<Buffer> | <TypedArray> | <DataView> 对传入的buffer
参数的引用。
从文件中读取数据,并将其存储在给定的缓冲区中。
如果未同时修改文件,当读取的字节数为零时,则到达文件末尾。
filehandle.readFile(options)
#
options
<Object> | <string>encoding
<string> | <null> 默认值:null
signal
<AbortSignal> 允许中止正在进行的读取文件
- 返回: <Promise> 成功读取时将使用文件内容履行。
如果未指定编码(使用
options.encoding
),则数据作为 <Buffer> 对象返回。 否则,数据将为字符串。
异步地读取文件的全部内容。
如果 options
是字符串,则它指定 encoding
。
<FileHandle> 必须支持读取。
如果在文件句柄上进行了一次或多次 filehandle.read()
调用,然后进行 filehandle.readFile()
调用,则将从当前位置读取数据,直到文件末尾。
它并不总是从文件的开头读取。
filehandle.readv(buffers[, position])
#
buffers
<Buffer[]> | <TypedArray[]> | <DataView[]>position
<integer> | <null> 要从中读取数据的文件的开头偏移量。 如果position
不是number
,则将从当前位置读取数据。 默认值:null
- 返回: <Promise> 成功时将使用包含以下两个属性的对象履行:
bytesRead
<integer> 读取的字节数buffers
<Buffer[]> | <TypedArray[]> | <DataView[]> 该属性包含对buffers
输入的引用。
从文件读取并写入 <ArrayBufferView> 的数组
filehandle.stat([options])
#
options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
- 返回: <Promise> 使用文件的 <fs.Stats> 履行。
filehandle.sync()
#
- 返回: <Promise> 成功时将使用
undefined
履行。
请求将打开文件描述符的所有数据刷新到存储设备。
具体实现是操作系统和设备特定的。
有关更多详细信息,请参考 POSIX fsync(2)
文档。
filehandle.truncate(len)
#
截断文件。
如果文件大于 len
个字节,则仅前 len
个字节将保留在文件中。
下面的示例仅保留文件的前四个字节:
import { open } from 'node:fs/promises';
let filehandle = null;
try {
filehandle = await open('temp.txt', 'r+');
await filehandle.truncate(4);
} finally {
await filehandle?.close();
}
如果文件先前小于 len
个字节,则将其扩展,并且扩展部分将使用空字节('\0'
)填充:
如果 len
为负数,则将使用 0
。
filehandle.utimes(atime, mtime)
#
更改 <FileHandle> 引用的对象的文件系统时间戳,然后在成功时不带参数解决 promise 。
filehandle.write(buffer, offset[, length[, position]])
#
buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer> 要开始写入数据的buffer
的起始位置。length
<integer> 要从buffer
写入的字节数。 默认值:buffer.byteLength - offset
position
<integer> | <null> 要写入来自buffer
的数据的文件的开头偏移量。 如果position
不是number
,则数据将被写入当前位置。 有关更多详细信息,请参阅 POSIXpwrite(2)
文档。 默认值:null
- 返回: <Promise>
将 buffer
写入文件。
使用包含以下两个属性的对象来解决 promise:
bytesWritten
<integer> 写入的字节数buffer
<Buffer> | <TypedArray> | <DataView> 对被写入的buffer
的引用。
在同一文件上多次使用 filehandle.write()
而不等待 promise 被解决(或拒绝)是不安全的。
对于这种情况,请使用 filehandle.createWriteStream()
。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。 内核会忽略位置参数,并始终将数据追加到文件末尾。
filehandle.write(buffer[, options])
#
buffer
<Buffer> | <TypedArray> | <DataView>options
<Object>- 返回: <Promise>
将 buffer
写入文件。
与上面的 filehandle.write
函数类似,此版本采用可选的 options
对象。
如果未指定 options
对象,则默认使用上述值。
filehandle.write(string[, position[, encoding]])
#
string
<string>position
<integer> | <null> 要写入来自string
的数据的文件的开头偏移量。 如果position
不是number
,则数据将写入当前位置。 有关更多详细信息,请参阅 POSIXpwrite(2)
文档。 默认值:null
encoding
<string> 预期的字符串编码。 默认值:'utf8'
- 返回: <Promise>
将 string
写入文件。
如果 string
不是字符串,则 promise 使用错误拒绝。
使用包含以下两个属性的对象来解决 promise:
在同一文件上多次使用 filehandle.write()
而不等待 promise 被解决(或拒绝)是不安全的。
对于这种情况,请使用 filehandle.createWriteStream()
。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。 内核会忽略位置参数,并始终将数据追加到文件末尾。
filehandle.writeFile(data, options)
#
data
<string> | <Buffer> | <TypedArray> | <DataView> | <AsyncIterable> | <Iterable> | <Stream>options
<Object> | <string>- 返回: <Promise>
异步地将数据写入文件,如果文件已经存在,则替换该文件。
data
可以是字符串、缓冲区、<AsyncIterable>、或 <Iterable> 对象。
成功时不带参数解决 promise。
如果 options
是字符串,则它指定 encoding
。
<FileHandle> 必须支持写入。
在同一文件上多次使用 filehandle.writeFile()
而不等待 promise 被解决(或拒绝)是不安全的。
如果在文件句柄上进行了一次或多次 filehandle.write()
调用,然后进行 filehandle.writeFile()
调用,则数据将从当前位置写入,直到文件末尾。
它并不总是从文件的开头写入。
filehandle.writev(buffers[, position])
#
buffers
<Buffer[]> | <TypedArray[]> | <DataView[]>position
<integer> | <null> 要写入来自buffers
的数据的文件的开头偏移量。 如果position
不是number
,则数据将被写入当前位置。 默认值:null
- 返回: <Promise>
将 <ArrayBufferView> 的数组写入文件。
使用包含以下两个属性的对象来解决 promise:
bytesWritten
<integer> 写入的字节数buffers
<Buffer[]> | <TypedArray[]> | <DataView[]> 对buffers
输入的引用。
在同一文件上多次调用 writev()
而不等待 promise 被解决(或拒绝)是不安全的。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。 内核会忽略位置参数,并始终将数据追加到文件末尾。
fsPromises.access(path[, mode])
#
path
<string> | <Buffer> | <URL>mode
<integer> 默认值:fs.constants.F_OK
- 返回: <Promise> 成功时将使用
undefined
履行。
测试用户对 path
指定的文件或目录的权限。
mode
参数是可选的整数,指定要执行的可访问性检查。
mode
应该是值 fs.constants.F_OK
或由 fs.constants.R_OK
、fs.constants.W_OK
和 fs.constants.X_OK
中的任何一个(例如 fs.constants.W_OK | fs.constants.R_OK
)的按位或组成的掩码。
查看文件访问的常量以获取可能的 mode
值。
如果可访问性检查成功,则不带值解决 promise。
如果任何可访问性检查失败,则使用 <Error> 对象拒绝 promise。
以下示例检查当前进程是否可以读写文件 /etc/passwd
。
import { access, constants } from 'node:fs/promises';
try {
await access('/etc/passwd', constants.R_OK | constants.W_OK);
console.log('can access');
} catch {
console.error('cannot access');
}
不建议在调用 fsPromises.open()
之前使用 fsPromises.access()
检查文件的可访问性。
这样做会引入竞争条件,因为其他进程可能会在两次调用之间更改文件的状态。
而是,用户代码应直接打开/读取/写入文件,并处理无法访问文件时引发的错误。
fsPromises.appendFile(path, data[, options])
#
path
<string> | <Buffer> | <URL> | <FileHandle> 文件名或 <FileHandle>data
<string> | <Buffer>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
mode
<integer> 默认值:0o666
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'a'
。
- 返回: <Promise> 成功时将使用
undefined
履行。
异步地将数据追加到文件,如果该文件尚不存在,则创建该文件。
data
可以是字符串或 <Buffer>。
如果 options
是字符串,则它指定 encoding
。
mode
选项仅影响新创建的文件。
有关详细信息,请参阅 fs.open()
。
可以将 path
指定为已打开用于追加(使用 fsPromises.open()
)的 <FileHandle>。
fsPromises.chmod(path, mode)
#
更改文件的权限。
fsPromises.chown(path, uid, gid)
#
更改文件的所有权。
fsPromises.copyFile(src, dest[, mode])
#
src
<string> | <Buffer> | <URL> 要复制的源文件名dest
<string> | <Buffer> | <URL> 复制操作的目标文件名mode
<integer> 指定复制操作行为的可选修饰符。 可以创建由两个或多个值的按位或组成的掩码(例如fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE
) 默认值:0
。fs.constants.COPYFILE_EXCL
: 如果dest
已经存在,则复制操作将失败。fs.constants.COPYFILE_FICLONE
: 复制操作将尝试创建写时复制引用链接。 如果平台不支持写时复制,则使用后备复制机制。fs.constants.COPYFILE_FICLONE_FORCE
: 复制操作将尝试创建写时复制引用链接。 如果平台不支持写时复制,则该操作将失败。
- 返回: <Promise> 成功时将使用
undefined
履行。
异步地将 src
复制到 dest
。
默认情况下,如果 dest
已经存在,则会被覆盖。
无法保证复制操作的原子性。 如果在打开目标文件进行写入后发生错误,则将尝试删除目标文件。
import { copyFile, constants } from 'node:fs/promises';
try {
await copyFile('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');
} catch {
console.log('The file could not be copied');
}
// 通过使用 COPYFILE_EXCL,如果 destination.txt 存在,则该操作将失败。
try {
await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
console.log('source.txt was copied to destination.txt');
} catch {
console.log('The file could not be copied');
}
fsPromises.cp(src, dest[, options])
#
src
<string> | <URL> 要复制的源路径。dest
<string> | <URL> 要复制到的目标路径。options
<Object>dereference
<boolean> 取消引用符号链接。 默认值:false
。errorOnExist
<boolean> 当force
为false
且目标存在时,则抛出错误。 默认值:false
。filter
<Function> 过滤复制文件/目录的函数。 返回true
则复制条目,返回false
则忽略它。 也可以返回解决为true
或false
的Promise
默认值:undefined
。force
<boolean> 覆盖现有的文件或目录。 如果将此设置为 false 并且目标存在,则复制操作将忽略错误。 使用errorOnExist
选项更改此行为。 默认值:true
。preserveTimestamps
<boolean> 当为true
时,则src
的时间戳将被保留。 默认值:false
。recursive
<boolean> 递归地复制目录 默认值:false
verbatimSymlinks
<boolean> 当为true
时,则符号链接的路径解析将被跳过。 默认值:false
- 返回: <Promise> 成功时将使用
undefined
履行。
将整个目录结构从 src
异步地复制到 dest
,包括子目录和文件。
当将目录复制到另一个目录时,不支持 globs,并且行为类似于 cp dir1/ dir2/
。
fsPromises.lchmod(path, mode)
#
更改符号链接的权限。
此方法仅在 macOS 上实现。
fsPromises.lchown(path, uid, gid)
#
更改符号链接上的所有权。
fsPromises.lutimes(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>- 返回: <Promise> 成功时将使用
undefined
履行。
以与 fsPromises.utimes()
相同的方式更改文件的访问和修改时间,不同之处在于,如果路径引用符号链接,则不会取消引用该链接:而是,符号链接本身的时间戳会更改。
fsPromises.link(existingPath, newPath)
#
existingPath
<string> | <Buffer> | <URL>newPath
<string> | <Buffer> | <URL>- 返回: <Promise> 成功时将使用
undefined
履行。
创建从 existingPath
到 newPath
的新链接。
有关更多详细信息,请参阅 POSIX link(2)
文档。
fsPromises.lstat(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
- 返回: <Promise> 使用给定的符号链接
path
的 <fs.Stats> 对象履行。
等效于 fsPromises.stat()
,除非 path
指向符号链接,在这种情况下,被统计的是链接本身,而不是其所引用的文件。
有关更多详细信息,请参考 POSIX lstat(2)
文档。
fsPromises.mkdir(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object> | <integer>- 返回: <Promise> 成功后,如果
recursive
为false
,则使用undefined
履行;如果recursive
为true
,则使用创建的第一个目录路径履行。
异步地创建目录。
可选的 options
参数可以是指定 mode
(权限和粘性位)的整数,也可以是具有 mode
属性和 recursive
属性(指示是否应创建父目录)的对象。
当 path
是已存在的目录时,调用 fsPromises.mkdir()
仅在 recursive
为 false 时才导致拒绝。
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);
}
const { mkdir } = require('node:fs/promises');
const { resolve, 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])
#
prefix
<string>options
<string> | <Object>encoding
<string> 默认值:'utf8'
- 返回: <Promise> 使用包含新创建的临时目录的文件系统路径的字符串来履行。
创建唯一的临时目录。
通过在所提供的 prefix
的末尾附加六个随机字符来生成唯一的目录名称。
由于平台的不一致,请避免在 prefix
中尾随 X
字符。
某些平台,尤其是 BSD,可能返回六个以上的随机字符,并将 prefix
中的尾随 X
字符替换为随机字符。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定要使用的字符编码)的对象。
import { mkdtemp } from 'node:fs/promises';
try {
await mkdtemp(path.join(os.tmpdir(), 'foo-'));
} catch (err) {
console.error(err);
}
fsPromises.mkdtemp()
方法会将六个随机选择的字符直接附加到 prefix
字符串。
例如,给定目录 /tmp
,如果要在 /tmp
内创建临时目录,则 prefix
必须以平台特定的尾随路径分隔符(require('node:path').sep
)结尾。
fsPromises.open(path, flags[, mode])
#
path
<string> | <Buffer> | <URL>flags
<string> | <number> 请参阅对文件系统flags
的支持。 默认值:'r'
。mode
<string> | <integer> 如果创建文件,则设置文件模式(权限和粘性位)。 默认值:0o666
(可读可写)- 返回: <Promise> 使用 <FileHandle> 对象履行。
打开 <FileHandle>。
有关更多详细信息,请参考 POSIX open(2)
文档。
在 Windows 上预留了一些字符(< > : " / \ | ? *
),如命名文件、路径和命名空间所记录。
在 NTFS 下,如果文件名包含冒号,则 Node.js 将打开文件系统流,如此 MSDN 页面所述。
fsPromises.opendir(path[, options])
#
异步地打开目录进行迭代扫描。
有关更多详细信息,请参阅 POSIX opendir(3)
文档。
创建 <fs.Dir>,其中包含用于从目录读取和清理目录的所有进一步的函数。
encoding
选项设置在打开目录和随后的读取操作时 path
的编码。
使用异步迭代的示例:
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])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>- 返回: <Promise> 使用目录中文件的名称数组(不包括
'.'
和'..'
)履行。
读取目录的内容。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于文件名的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的文件名将作为 <Buffer> 对象传入。
如果 options.withFileTypes
设置为 true
,则解决的数组将包含 <fs.Dirent> 对象。
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])
#
path
<string> | <Buffer> | <URL> | <FileHandle> 文件名或FileHandle
options
<Object> | <string>encoding
<string> | <null> 默认值:null
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'r'
。signal
<AbortSignal> 允许中止正在进行的读取文件
- 返回: <Promise> 使用文件的内容履行。
异步地读取文件的全部内容。
如果未指定编码(使用 options.encoding
),则数据作为 <Buffer> 对象返回。
否则,数据将为字符串。
如果 options
是字符串,则它指定编码。
当 path
是目录时,fsPromises.readFile()
的行为是特定于平台的。
在 macOS、Linux 和 Windows 上,promise 将使用错误拒绝。
在 FreeBSD 上,将返回目录内容的表示。
可以使用 <AbortSignal> 中止正在进行的 readFile
。
如果请求中止,则返回的 promise 将使用 AbortError
拒绝:
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])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
- 返回: <Promise> 成功时将使用
linkString
履行。
读取 path
引用的符号链接的内容。
有关更多详细信息,请参阅 POSIX readlink(2)
文档。
成功时使用 linkString
解决 promise。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于返回的链接路径的字符编码)的对象。
如果将 encoding
设置为 'buffer'
,则返回的链接路径将作为 <Buffer> 对象传入。
fsPromises.realpath(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
- 返回: <Promise> 成功时将使用解析的路径履行。
使用与 fs.realpath.native()
函数相同的语义确定 path
的实际位置。
仅支持可以转换为 UTF8 字符串的路径。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于路径的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的路径将作为 <Buffer> 对象传入。
在 Linux 上,将 Node.js 与 musl libc 链接时,必须将 procfs 文件系统挂载在 /proc
上,此函数才能起作用。
Glibc 没有此限制。
fsPromises.rename(oldPath, newPath)
#
oldPath
<string> | <Buffer> | <URL>newPath
<string> | <Buffer> | <URL>- 返回: <Promise> 成功时将使用
undefined
履行。
将 oldPath
重命名为 newPath
。
fsPromises.rmdir(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,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 命令的行为,则使用具有选项 { recursive: true, force: true }
的 fsPromises.rm()
。
fsPromises.rm(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>force
<boolean> 当为true
时,如果path
不存在,则异常将被忽略。 默认值:false
。maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,Node.js 将在每次尝试时以retryDelay
毫秒的线性退避等待时间重试该操作。 此选项表示重试次数。 如果recursive
选项不为true
,则忽略此选项。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归目录删除。 在递归模式下,操作将在失败时重试。 默认值:false
。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则忽略此选项。 默认值:100
。
- 返回: <Promise> 成功时将使用
undefined
履行。
删除文件和目录(在标准 POSIX rm
实用工具上建模)。
fsPromises.stat(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
- 返回: <Promise> 使用给定的
path
的 <fs.Stats> 对象履行。
fsPromises.symlink(target, path[, type])
#
target
<string> | <Buffer> | <URL>path
<string> | <Buffer> | <URL>type
<string> 默认值:'file'
- 返回: <Promise> 成功时将使用
undefined
履行。
创建符号链接。
type
参数仅在 Windows 平台上使用,可以是 'dir'
、'file'
或 'junction'
之一。
Windows 交接点要求目标路径是绝对路径。
使用 'junction'
时,target
参数将自动规范化为绝对路径。
fsPromises.truncate(path[, len])
#
将 path
上的内容截断(缩短或延长长度)到 len
个字节。
fsPromises.unlink(path)
#
如果 path
指向符号链接,则删除该链接,但不影响链接所指向的文件或目录。
如果 path
指向的文件路径不是符号链接,则删除文件。
有关更多详细信息,请参阅 POSIX unlink(2)
文档。
fsPromises.utimes(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>- 返回: <Promise> 成功时将使用
undefined
履行。
更改 path
引用的对象的文件系统时间戳。
atime
和 mtime
参数遵循以下规则:
- 值可以是代表 Unix 纪元时间的数字、
Date
、或数字字符串(例如'123456789.0'
)。 - 如果该值不能转换为数字,或者是
NaN
、Infinity
或-Infinity
,则会抛出Error
。
fsPromises.watch(filename[, options])
#
filename
<string> | <Buffer> | <URL>options
<string> | <Object>persistent
<boolean> 指示只要正在监视文件,进程是否应继续运行。 默认值:true
。recursive
<boolean> 指示是应监视所有子目录,还是仅监视当前目录。 这在指定目录时适用,并且仅在受支持的平台上有效(请参见注意事项)。 默认值:false
。encoding
<string> 指定用于传给监听器的文件名的字符编码。 默认值:'utf8'
。signal
<AbortSignal> 用于指示监视器何时应停止的 <AbortSignal>。
- 返回: <AsyncIterator> 具有以下属性的对象:
返回异步迭代器,其监视 filename
上的更改,其中 filename
是文件或目录。
const { watch } = require('node:fs/promises');
const ac = new AbortController();
const { signal } = ac;
setTimeout(() => ac.abort(), 10000);
(async () => {
try {
const watcher = watch(__filename, { signal });
for await (const event of watcher)
console.log(event);
} catch (err) {
if (err.name === 'AbortError')
return;
throw err;
}
})();
在大多数平台上,只要目录中文件名出现或消失,就会触发 'rename'
。
fs.watch()
的所有注意事项也适用于 fsPromises.watch()
。
fsPromises.writeFile(file, data[, options])
#
file
<string> | <Buffer> | <URL> | <FileHandle> 文件名或FileHandle
data
<string> | <Buffer> | <TypedArray> | <DataView> | <AsyncIterable> | <Iterable> | <Stream>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
mode
<integer> 默认值:0o666
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'w'
。signal
<AbortSignal> 允许中止正在进行的写入文件
- 返回: <Promise> 成功时将使用
undefined
履行。
异步地将数据写入文件,如果文件已经存在,则替换该文件。
data
可以是字符串、缓冲区、<AsyncIterable>、或 <Iterable> 对象。
如果 data
是缓冲区,则忽略 encoding
选项。
如果 options
是字符串,则它指定编码。
mode
选项仅影响新创建的文件。
有关详细信息,请参阅 fs.open()
。
任何指定的 <FileHandle> 都必须支持写入。
在同一个文件上多次使用 fsPromises.writeFile()
而不等待 promise 被解决是不安全的。
与 fsPromises.readFile
类似,fsPromises.writeFile
是一个便捷的方法,其在内部执行多次 write
调用以写入传给它的缓冲区。
对于性能敏感的代码,则考虑使用 fs.createWriteStream()
或 filehandle.createWriteStream()
。
可以使用 <AbortSignal> 取消 fsPromises.writeFile()
。
取消是"尽力而为"的,并且可能仍会写入一些数据。
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
#
返回一个包含文件系统操作常用常量的对象。
对象与 fs.constants
相同。
有关详细信息,请参阅 FS 常量。
回调的 API#
回调的 API 异步地执行所有操作,不会阻塞事件循环,然后在完成或错误时调用回调函数。
回调的 API 使用底层 Node.js 线程池在事件循环线程之外执行文件系统操作。 这些操作不是同步的也不是线程安全的。 对同一文件执行多个并发修改时必须小心,否则可能会损坏数据。
fs.access(path[, mode], callback)
#
path
<string> | <Buffer> | <URL>mode
<integer> 默认值:fs.constants.F_OK
callback
<Function>err
<Error>
测试用户对 path
指定的文件或目录的权限。
mode
参数是可选的整数,指定要执行的可访问性检查。
mode
应该是值 fs.constants.F_OK
或由 fs.constants.R_OK
、fs.constants.W_OK
和 fs.constants.X_OK
中的任何一个(例如 fs.constants.W_OK | fs.constants.R_OK
)的按位或组成的掩码。
查看文件访问的常量以获取可能的 mode
值。
最后一个参数 callback
是回调函数,其使用一个可能的错误参数调用。
如果任何可访问性检查失败,则错误参数将是 Error
对象。
以下示例检查 package.json
是否存在,以及是否可读或可写。
import { access, constants } from 'node:fs';
const file = 'package.json';
// 检查当前目录中是否存在该文件。
access(file, constants.F_OK, (err) => {
console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
});
// 检查文件是否可读。
access(file, constants.R_OK, (err) => {
console.log(`${file} ${err ? 'is not readable' : 'is readable'}`);
});
// 检查文件是否可写。
access(file, constants.W_OK, (err) => {
console.log(`${file} ${err ? 'is not writable' : 'is writable'}`);
});
// 检查文件是否可读可写。
access(file, constants.R_OK | constants.W_OK, (err) => {
console.log(`${file} ${err ? 'is not' : 'is'} readable and writable`);
});
在调用 fs.open()
、fs.readFile()
或 fs.writeFile()
之前,不要使用 fs.access()
检查文件的可访问性。
这样做会引入竞争条件,因为其他进程可能会在两次调用之间更改文件的状态。
而是,用户代码应直接打开/读取/写入文件,并处理无法访问文件时引发的错误。
写入(不推荐)
import { access, open, close } from 'node:fs';
access('myfile', (err) => {
if (!err) {
console.error('myfile already exists');
return;
}
open('myfile', 'wx', (err, fd) => {
if (err) throw err;
try {
writeMyData(fd);
} finally {
close(fd, (err) => {
if (err) throw err;
});
}
});
});
写入(推荐)
import { open, close } from 'node:fs';
open('myfile', 'wx', (err, fd) => {
if (err) {
if (err.code === 'EEXIST') {
console.error('myfile already exists');
return;
}
throw err;
}
try {
writeMyData(fd);
} finally {
close(fd, (err) => {
if (err) throw err;
});
}
});
读取(不推荐)
import { access, open, close } from 'node:fs';
access('myfile', (err) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('myfile does not exist');
return;
}
throw err;
}
open('myfile', 'r', (err, fd) => {
if (err) throw err;
try {
readMyData(fd);
} finally {
close(fd, (err) => {
if (err) throw err;
});
}
});
});
读取(推荐)
import { open, close } from 'node:fs';
open('myfile', 'r', (err, fd) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('myfile does not exist');
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)
#
path
<string> | <Buffer> | <URL> | <number> 文件名或文件描述符data
<string> | <Buffer>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
mode
<integer> 默认值:0o666
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'a'
。
callback
<Function>err
<Error>
异步地将数据追加到文件,如果该文件尚不存在,则创建该文件。
data
可以是字符串或 <Buffer>。
mode
选项仅影响新创建的文件。
有关详细信息,请参阅 fs.open()
。
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
是字符串,则它指定编码:
import { appendFile } from 'node:fs';
appendFile('message.txt', 'data to append', 'utf8', callback);
可以将 path
指定为已打开用于追加(使用 fs.open()
或 fs.openSync()
)的数字文件描述符。
文件描述符不会自动关闭。
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)
#
异步地更改文件的权限。 除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX chmod(2)
文档。
import { chmod } from 'node:fs';
chmod('my_file.txt', 0o775, (err) => {
if (err) throw err;
console.log('The permissions for file "my_file.txt" have been changed!');
});
文件的模式#
fs.chmod()
和 fs.chmodSync()
方法中使用的 mode
参数是使用以下常量的逻辑或创建的数字位掩码:
常量 | 八进制 | 描述 |
---|---|---|
fs.constants.S_IRUSR | 0o400 | 所有者可读取 |
fs.constants.S_IWUSR | 0o200 | 所有者可写入 |
fs.constants.S_IXUSR | 0o100 | 所有者可执行/搜索 |
fs.constants.S_IRGRP | 0o40 | 群组可读取 |
fs.constants.S_IWGRP | 0o20 | 群组可写入 |
fs.constants.S_IXGRP | 0o10 | 群组可执行/搜索 |
fs.constants.S_IROTH | 0o4 | 其他人可读取 |
fs.constants.S_IWOTH | 0o2 | 其他人可写入 |
fs.constants.S_IXOTH | 0o1 | 其他人可执行/搜索 |
构建 mode
的一种更简单的方法是使用三个八进制数字的序列(例如 765
)。
最左边的数字(示例中的 7
)指定文件所有者的权限。
中间的数字(示例中的 6
)指定群组的权限。
最右边的数字(示例中的 5
)指定其他人的权限。
数值 | 描述 |
---|---|
7 | 可读、可写和可执行 |
6 | 可读和可写 |
5 | 可读和可执行 |
4 | 只读 |
3 | 可写和可执行 |
2 | 只写 |
1 | 只可执行 |
0 | 无权限 |
例如,八进制值 0o765
表示:
- 所有者可以读取、写入、以及执行文件。
- 群组可以读取和写入文件。
- 其他人可以读取和执行文件。
在需要文件模式的地方使用原始数字时,任何大于 0o777
的值都可能导致特定于平台的行为不支持一致工作。
因此,像 S_ISVTX
、S_ISGID
或 S_ISUID
这样的常量不会在 fs.constants
中暴露。
注意事项:在 Windows 上只能更改写入权限,并没有实现群组、所有者或其他人权限之间的区别。
fs.chown(path, uid, gid, callback)
#
异步地更改文件的所有者和群组。 除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX chown(2)
文档。
fs.close(fd[, callback])
#
fd
<integer>callback
<Function>err
<Error>
关闭文件描述符。 除了可能的异常之外,没有为完成回调提供任何参数。
通过任何其他 fs
操作对当前正在使用的任何文件描述符 (fd
) 调用 fs.close()
,则可能会导致未定义的行为。
有关更多详细信息,请参阅 POSIX close(2)
文档。
fs.copyFile(src, dest[, mode], callback)
#
src
<string> | <Buffer> | <URL> 要复制的源文件名dest
<string> | <Buffer> | <URL> 复制操作的目标文件名mode
<integer> 复制操作的修饰符。 默认值:0
。callback
<Function>
异步地将 src
复制到 dest
。
默认情况下,如果 dest
已经存在,则会被覆盖。
除了可能的异常之外,没有给回调函数提供任何参数。
Node.js 不保证复制操作的原子性。
如果在打开目标文件进行写入后发生错误,Node.js 将尝试删除目标文件。
mode
是可选的整数,用于指定复制操作的行为。
可以创建由两个或多个值的按位或组成的掩码(例如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE
)。
fs.constants.COPYFILE_EXCL
: 如果dest
已经存在,则复制操作将失败。fs.constants.COPYFILE_FICLONE
: 复制操作将尝试创建写时复制引用链接。 如果平台不支持写时复制,则使用后备复制机制。fs.constants.COPYFILE_FICLONE_FORCE
: 复制操作将尝试创建写时复制引用链接。 如果平台不支持写时复制,则该操作将失败。
import { copyFile, constants } from 'node:fs';
function callback(err) {
if (err) throw err;
console.log('source.txt was copied to 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)
#
src
<string> | <URL> 要复制的源路径。dest
<string> | <URL> 要复制到的目标路径。options
<Object>dereference
<boolean> 取消引用符号链接。 默认值:false
。errorOnExist
<boolean> 当force
为false
且目标存在时,则抛出错误。 默认值:false
。filter
<Function> 过滤复制文件/目录的函数。 返回true
则复制条目,返回false
则忽略它。 也可以返回解决为true
或false
的Promise
默认值:undefined
。force
<boolean> 覆盖现有的文件或目录。 如果将此设置为 false 并且目标存在,则复制操作将忽略错误。 使用errorOnExist
选项更改此行为。 默认值:true
。preserveTimestamps
<boolean> 当为true
时,则src
的时间戳将被保留。 默认值:false
。recursive
<boolean> 递归地复制目录 默认值:false
verbatimSymlinks
<boolean> 当为true
时,则符号链接的路径解析将被跳过。 默认值:false
callback
<Function>
将整个目录结构从 src
异步地复制到 dest
,包括子目录和文件。
当将目录复制到另一个目录时,不支持 globs,并且行为类似于 cp dir1/ dir2/
。
fs.createReadStream(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>flags
<string> 请参阅对文件系统flags
的支持。 默认值:'r'
。encoding
<string> 默认值:null
fd
<integer> | <FileHandle> 默认值:null
mode
<integer> 默认值:0o666
autoClose
<boolean> 默认值:true
emitClose
<boolean> 默认值:true
start
<integer>end
<integer> 默认值:Infinity
highWaterMark
<integer> 默认值:64 * 1024
fs
<Object> | <null> 默认值:null
- 返回: <fs.ReadStream>
与 <stream.Readable> 的 16 KiB 默认 highWaterMark
不同,此方法返回的流的默认 highWaterMark
为 64 KiB。
options
可以包括 start
和 end
值,以从文件中读取一定范围的字节,而不是整个文件。
start
和 end
都包含在内并且从 0 开始计数,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 范围内。
如果指定了 fd
并且 start
被省略或 undefined
,则 fs.createReadStream()
从当前文件位置顺序读取。
encoding
可以是 <Buffer> 接受的任何一种。
如果指定了 fd
,则 ReadStream
将忽略 path
参数并使用指定的文件描述符。
这意味着不会触发 'open'
事件。
fd
应该是阻塞的;非阻塞 fd
应该传给 <net.Socket>。
如果 fd
指向仅支持阻塞读取的字符设备(例如键盘或声卡),则读取操作不会在数据可用之前完成。
这可以防止进程退出和流自然关闭。
默认情况下,流将在销毁后触发 'close'
事件。
将 emitClose
选项设置为 false
以更改此行为。
通过提供 fs
选项,可以覆盖 open
、read
和 close
的相应 fs
实现。
当提供了 fs
选项时,则需要覆盖 read
。
如果未提供 fd
,则还需要覆盖 open
。
如果 autoClose
是 true
,则还需要覆盖 close
。
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 个字节的示例:
import { createReadStream } from 'node:fs';
createReadStream('sample.txt', { start: 90, end: 99 });
如果 options
是字符串,则它指定编码。
fs.createWriteStream(path[, options])
#
options
还可以包括 start
选项,以允许在文件开头的某个位置写入数据,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 范围内。
修改文件而不是替换它可能需要将 flags
选项设置为 r+
而不是默认的 w
。
encoding
可以是 <Buffer> 接受的任何一种。
如果将 autoClose
设置为 true(默认行为),则在 'error'
或 'finish'
时文件描述符将自动关闭。
如果 autoClose
为 false,则即使出现错误,文件描述符也不会关闭。
关闭它并确保没有文件描述符泄漏是应用程序的责任。
默认情况下,流将在销毁后触发 'close'
事件。
将 emitClose
选项设置为 false
以更改此行为。
通过提供 fs
选项,可以覆盖 open
、write
、writev
和 close
的相应 fs
实现。
在没有 writev()
的情况下覆盖 write()
会降低性能,因为某些优化 (_writev()
) 将被禁用。
当提供了 fs
选项时,则至少需要覆盖 write
和 writev
之一。
如果没有提供 fd
选项,则还需要覆盖 open
。
如果 autoClose
是 true
,则还需要覆盖 close
。
与 <fs.ReadStream> 一样,如果指定了 fd
,则 <fs.WriteStream> 将忽略 path
参数并使用指定的文件描述符。
这意味着不会触发 'open'
事件。
fd
应该是阻塞的;非阻塞 fd
应该传给 <net.Socket>。
如果 options
是字符串,则它指定编码。
fs.exists(path, callback)
#
path
<string> | <Buffer> | <URL>callback
<Function>exists
<boolean>
通过检查文件系统来测试给定的路径是否存在。
然后使用 true 或 false 调用 callback
参数:
import { exists } from 'node:fs';
exists('/etc/passwd', (e) => {
console.log(e ? 'it exists' : 'no passwd!');
});
此回调的参数与其他 Node.js 回调不一致。
通常,Node.js 回调的第一个参数是 err
参数,后跟可选的其他参数。
fs.exists()
回调只有一个布尔参数。
这是推荐 fs.access()
而不是 fs.exists()
的原因之一。
不建议在调用 fs.open()
、fs.readFile()
或 fs.writeFile()
之前使用 fs.exists()
检查文件是否存在。
这样做会引入竞争条件,因为其他进程可能会在两次调用之间更改文件的状态。
而是,用户代码应该直接打开/读取/写入文件,并在文件不存在时处理引发的错误。
写入(不推荐)
import { exists, open, close } from 'node:fs';
exists('myfile', (e) => {
if (e) {
console.error('myfile already exists');
} else {
open('myfile', 'wx', (err, fd) => {
if (err) throw err;
try {
writeMyData(fd);
} finally {
close(fd, (err) => {
if (err) throw err;
});
}
});
}
});
写入(推荐)
import { open, close } from 'node:fs';
open('myfile', 'wx', (err, fd) => {
if (err) {
if (err.code === 'EEXIST') {
console.error('myfile already exists');
return;
}
throw err;
}
try {
writeMyData(fd);
} finally {
close(fd, (err) => {
if (err) throw err;
});
}
});
读取(不推荐)
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 does not exist');
}
});
读取(推荐)
import { open, close } from 'node:fs';
open('myfile', 'r', (err, fd) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('myfile does not exist');
return;
}
throw err;
}
try {
readMyData(fd);
} finally {
close(fd, (err) => {
if (err) throw err;
});
}
});
上面的“不推荐”示例检查是否存在,然后使用该文件;“推荐”示例更好,因为它们直接使用文件并处理错误(如果有)。
一般来说,只有在文件不被直接使用时才检查文件是否存在,例如当它的存在是来自另一个进程的信号时。
fs.fchmod(fd, mode, callback)
#
fd
<integer>mode
<string> | <integer>callback
<Function>err
<Error>
设置文件的权限。 除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX fchmod(2)
文档。
fs.fchown(fd, uid, gid, callback)
#
fd
<integer>uid
<integer>gid
<integer>callback
<Function>err
<Error>
设置文件的所有者。 除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX fchown(2)
文档。
fs.fdatasync(fd, callback)
#
fd
<integer>callback
<Function>err
<Error>
将与文件关联的所有当前排队的 I/O 操作强制为操作系统的同步 I/O 完成状态。
有关详细信息,请参阅 POSIX fdatasync(2)
文档。
除了可能的异常之外,没有为完成回调提供任何参数。
fs.fstat(fd[, options], callback)
#
fd
<integer>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
callback
<Function>err
<Error>stats
<fs.Stats>
使用文件描述符的 <fs.Stats> 调用回调。
有关更多详细信息,请参阅 POSIX fstat(2)
文档。
fs.fsync(fd, callback)
#
fd
<integer>callback
<Function>err
<Error>
请求将打开文件描述符的所有数据刷新到存储设备。
具体实现是操作系统和设备特定的。
有关更多详细信息,请参考 POSIX fsync(2)
文档。
除了可能的异常之外,没有为完成回调提供任何参数。
fs.ftruncate(fd[, len], callback)
#
fd
<integer>len
<integer> 默认值:0
callback
<Function>err
<Error>
截断文件描述符。 除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX ftruncate(2)
文档。
如果文件描述符引用的文件大于 len
个字节,则文件中将仅保留前 len
个字节。
例如,以下程序仅保留文件的前四个字节:
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)
#
fd
<integer>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>callback
<Function>err
<Error>
更改提供的文件描述符引用的对象的文件系统时间戳。
参见 fs.utimes()
。
fs.lchmod(path, mode, callback)
#
path
<string> | <Buffer> | <URL>mode
<integer>callback
<Function>err
<Error> | <AggregateError>
更改符号链接的权限。 除了可能的异常之外,没有为完成回调提供任何参数。
此方法仅在 macOS 上实现。
有关更多详细信息,请参阅 POSIX lchmod(2)
文档。
fs.lchown(path, uid, gid, callback)
#
设置符号链接的所有者。 除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX lchown(2)
文档。
fs.lutimes(path, atime, mtime, callback)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>callback
<Function>err
<Error>
以与 fs.utimes()
相同的方式更改文件的访问和修改时间,不同之处在于,如果路径引用符号链接,则不会取消引用该链接:而是,符号链接本身的时间戳会更改。
除了可能的异常之外,没有为完成回调提供任何参数。
fs.link(existingPath, newPath, callback)
#
existingPath
<string> | <Buffer> | <URL>newPath
<string> | <Buffer> | <URL>callback
<Function>err
<Error>
创建从 existingPath
到 newPath
的新链接。
有关更多详细信息,请参阅 POSIX link(2)
文档。
除了可能的异常之外,没有为完成回调提供任何参数。
fs.lstat(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
callback
<Function>err
<Error>stats
<fs.Stats>
获取路径引用的符号链接的 <fs.Stats>。
回调有两个参数 (err, stats)
,其中 stats
是 <fs.Stats> 对象。
lstat()
与 stat()
相同,除了如果 path
是符号链接,则被统计的是链接本身,而不是它引用的文件。
有关更多详细信息,请参阅 POSIX lstat(2)
文档。
fs.mkdir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object> | <integer>callback
<Function>err
<Error>path
<string> | <undefined> 仅当创建目录时将recursive
设置为true
。
异步地创建目录。
回调给出一个可能的异常和创建的第一个目录路径(如果 recursive
为 true
),(err[, path])
。
当 recursive
为 true
时,如果没有创建目录,则 path
仍然为 undefined
。
可选的 options
参数可以是指定 mode
(权限和粘性位)的整数,也可以是具有 mode
属性和 recursive
属性(指示是否应创建父目录)的对象。
当 path
是已存在的目录时,调用 fs.mkdir()
仅在 recursive
为 false 时才导致错误。
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()
也会导致错误:
import { mkdir } from 'node:fs';
mkdir('/', { recursive: true }, (err) => {
// => [Error: EPERM: operation not permitted, mkdir 'C:\']
});
有关更多详细信息,请参阅 POSIX mkdir(2)
文档。
fs.mkdtemp(prefix[, options], callback)
#
prefix
<string>options
<string> | <Object>encoding
<string> 默认值:'utf8'
callback
<Function>
创建唯一的临时目录。
生成六个随机字符,附加在所需的 prefix
后面以创建唯一的临时目录。
由于平台的不一致,请避免在 prefix
中尾随 X
字符。
某些平台,尤其是 BSD,可能返回六个以上的随机字符,并将 prefix
中的尾随 X
字符替换为随机字符。
创建的目录路径作为字符串传递给回调的第二个参数。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定要使用的字符编码)的对象。
import { mkdtemp } from 'node:fs';
mkdtemp(path.join(os.tmpdir(), 'foo-'), (err, directory) => {
if (err) throw err;
console.log(directory);
// 打印: /tmp/foo-itXde2 or C:\Users\...\AppData\Local\Temp\foo-itXde2
});
fs.mkdtemp()
方法会将六个随机选择的字符直接附加到 prefix
字符串。
例如,给定目录 /tmp
,如果要在 /tmp
内创建临时目录,则 prefix
必须以平台特定的尾随路径分隔符(require('node:path').sep
)结尾。
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)
#
path
<string> | <Buffer> | <URL>flags
<string> | <number> 请参阅对文件系统flags
的支持。 默认值:'r'
。mode
<string> | <integer> 默认值:0o666
(可读可写)callback
<Function>
异步地打开文件。
有关更多详细信息,请参阅 POSIX open(2)
文档。
mode
设置文件模式(权限和粘滞位),但前提是文件已创建。
在 Windows 上,只能操作写入权限;请参阅 fs.chmod()
。
回调有两个参数 (err, fd)
。
在 Windows 上预留了一些字符(< > : " / \ | ? *
),如命名文件、路径和命名空间所记录。
在 NTFS 下,如果文件名包含冒号,则 Node.js 将打开文件系统流,如此 MSDN 页面所述。
基于 fs.open()
的函数也表现出这种行为:fs.writeFile()
、fs.readFile()
等。
fs.opendir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>callback
<Function>
异步地打开目录。
有关更多详细信息,请参阅 POSIX opendir(3)
文档。
创建 <fs.Dir>,其中包含用于从目录读取和清理目录的所有进一步的函数。
encoding
选项设置在打开目录和随后的读取操作时 path
的编码。
fs.read(fd, buffer, offset, length, position, callback)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView> 数据将写入的缓冲区。offset
<integer> 要写入数据的buffer
中的位置。length
<integer> 读取的字节数。position
<integer> | <bigint> | <null> 指定从文件中开始读取的位置。 如果position
为null
或-1
,则将从当前文件位置读取数据,并更新文件位置。 如果position
是整数,则文件位置将保持不变。callback
<Function>
从 fd
指定的文件中读取数据。
回调被赋予三个参数,(err, bytesRead, buffer)
。
如果未同时修改文件,当读取的字节数为零时,则到达文件末尾。
如果此方法作为其 util.promisify()
版本被调用,则返回具有 bytesRead
和 buffer
属性的 Object
的 promise。
fs.read(fd[, options], callback)
#
fd
<integer>options
<Object>buffer
<Buffer> | <TypedArray> | <DataView> 默认值:Buffer.alloc(16384)
offset
<integer> 默认值:0
length
<integer> 默认值:buffer.byteLength - offset
position
<integer> | <bigint> | <null> 默认值:null
callback
<Function>
与 fs.read()
函数类似,此版本采用可选的 options
对象。
如果未指定 options
对象,则默认使用上述值。
fs.read(fd, buffer[, options], callback)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView> 数据将写入的缓冲区。options
<Object>callback
<Function>
与 fs.read()
函数类似,此版本采用可选的 options
对象。
如果未指定 options
对象,则默认使用上述值。
fs.readdir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>callback
<Function>err
<Error>files
<string[]> | <Buffer[]> | <fs.Dirent[]>
读取目录的内容。
回调有两个参数 (err, files)
,其中 files
是目录中文件名的数组,不包括 '.'
和 '..'
。
有关更多详细信息,请参阅 POSIX readdir(3)
文档。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于传给回调的文件名的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的文件名将作为 <Buffer> 对象传入。
如果 options.withFileTypes
设置为 true
,则 files
数组将包含 <fs.Dirent> 对象。
fs.readFile(path[, options], callback)
#
path
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符options
<Object> | <string>encoding
<string> | <null> 默认值:null
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'r'
。signal
<AbortSignal> 允许中止正在进行的读取文件
callback
<Function>err
<Error> | <AggregateError>data
<string> | <Buffer>
异步地读取文件的全部内容。
import { readFile } from 'node:fs';
readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
回调传入了两个参数 (err, data)
,其中 data
是文件的内容。
如果未指定编码,则返回原始缓冲区。
如果 options
是字符串,则它指定编码:
import { readFile } from 'node:fs';
readFile('/etc/passwd', 'utf8', callback);
当路径是目录时,fs.readFile()
和 fs.readFileSync()
的行为是特定于平台的。
在 macOS、Linux 和 Windows 上,将返回错误。
在 FreeBSD 上,将返回目录内容的表示。
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
调用:
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
执行。
文件描述符#
- 任何指定的文件描述符都必须支持读取。
- 如果将文件描述符指定为
path
,则它将不会自动关闭。 - 读数将从当前位置开始。
例如,如果文件已经具有
'Hello World'
并且使用文件描述符读取了六个字节,则使用相同文件描述符对fs.readFile()
的调用将得到'World'
,而不是'Hello World'
。
性能考量#
fs.readFile()
方法每次一块地异步读取文件内容到内存中,允许事件循环在每个块之间转换。
这允许读取操作对可能使用底层 libuv 线程池的其他活动的影响较小,但意味着将完整文件读入内存需要更长的时间。
额外的读取开销在不同的系统上可能会有很大差异,并且取决于正在读取的文件类型。 如果文件类型不是常规文件(例如管道)并且 Node.js 无法确定实际文件大小,则每次读取操作将加载 64 KiB 的数据。 对于常规文件,每次读取将处理 512 KiB 的数据。
对于需要尽可能快地读取文件内容的应用程序,最好直接使用 fs.read()
并让应用程序代码管理读取文件本身的全部内容。
Node.js GitHub 问题 #25741 提供了有关不同 Node.js 版本中多个文件大小的 fs.readFile()
性能的详细信息和详细分析。
fs.readlink(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
callback
<Function>
读取 path
引用的符号链接的内容。
回调有两个参数 (err, linkString)
。
有关更多详细信息,请参阅 POSIX readlink(2)
文档。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于传给回调的链接路径的字符编码)的对象。
如果将 encoding
设置为 'buffer'
,则返回的链接路径将作为 <Buffer> 对象传入。
fs.readv(fd, buffers[, position], callback)
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer> | <null> 默认值:null
callback
<Function>err
<Error>bytesRead
<integer>buffers
<ArrayBufferView[]>
从 fd
指定的文件中读取并使用 readv()
写入 ArrayBufferView
数组。
position
是从文件开头应该读取数据的偏移量。
如果 typeof position !== 'number'
,则从当前位置读取数据。
回调将被赋予三个参数:err
、bytesRead
和 buffers
。
bytesRead
是从文件中读取的字节数。
如果此方法作为其 util.promisify()
版本被调用,则返回具有 bytesRead
和 buffers
属性的 Object
的 promise。
fs.realpath(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
callback
<Function>
通过解析 .
、..
和符号链接异步地计算规范路径名。
规范路径名不一定是唯一的。 硬链接和绑定挂载可以通过许多路径名暴露文件系统实体。
此函数的行为类似于 realpath(3)
,但有一些例外:
-
在不区分大小写的文件系统上不执行大小写转换。
-
符号链接的最大数量与平台无关,并且通常(远)高于原生
realpath(3)
实现支持的数量。
callback
有两个参数 (err, resolvedPath)
。
可以使用 process.cwd
来解析相对路径。
仅支持可以转换为 UTF8 字符串的路径。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于传给回调的路径的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的路径将作为 <Buffer> 对象传入。
如果 path
解析为套接字或管道,则该函数将返回该对象的系统相关名称。
fs.realpath.native(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
callback
<Function>
异步的 realpath(3)
。
callback
有两个参数 (err, resolvedPath)
。
仅支持可以转换为 UTF8 字符串的路径。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于传给回调的路径的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的路径将作为 <Buffer> 对象传入。
在 Linux 上,将 Node.js 与 musl libc 链接时,必须将 procfs 文件系统挂载在 /proc
上,此函数才能起作用。
Glibc 没有此限制。
fs.rename(oldPath, newPath, callback)
#
oldPath
<string> | <Buffer> | <URL>newPath
<string> | <Buffer> | <URL>callback
<Function>err
<Error>
将 oldPath
处的文件异步重命名为作为 newPath
提供的路径名。
如果 newPath
已经存在,则它将被覆盖。
如果 newPath
是目录,则会引发错误。
除了可能的异常之外,没有为完成回调提供任何参数。
另见: rename(2)
。
import { rename } from 'node:fs';
rename('oldFile.txt', 'newFile.txt', (err) => {
if (err) throw err;
console.log('Rename complete!');
});
fs.rmdir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,Node.js 将在每次尝试时以retryDelay
毫秒的线性退避等待时间重试该操作。 此选项表示重试次数。 如果recursive
选项不为true
,则忽略此选项。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归目录删除。 在递归模式下,操作将在失败时重试。 默认值:false
。 已弃用。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则忽略此选项。 默认值:100
。
callback
<Function>err
<Error>
异步的 rmdir(2)
。
除了可能的异常之外,没有为完成回调提供任何参数。
在文件(而不是目录)上使用 fs.rmdir()
,则在 Windows 上会导致 ENOENT
错误,在 POSIX 上会导致 ENOTDIR
错误。
要获得类似于 rm -rf
Unix 命令的行为,则使用具有选项 { recursive: true, force: true }
的 fs.rm()
。
fs.rm(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>force
<boolean> 当为true
时,如果path
不存在,则异常将被忽略。 默认值:false
。maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,Node.js 将在每次尝试时以retryDelay
毫秒的线性退避等待时间重试该操作。 此选项表示重试次数。 如果recursive
选项不为true
,则忽略此选项。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归删除。 在递归模式下,操作将在失败时重试。 默认值:false
。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则忽略此选项。 默认值:100
。
callback
<Function>err
<Error>
异步地删除文件和目录(以标准 POSIX rm
实用工具为模型)。
除了可能的异常之外,没有为完成回调提供任何参数。
fs.stat(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
callback
<Function>err
<Error>stats
<fs.Stats>
异步的 stat(2)
。
回调有两个参数 (err, stats)
,其中 stats
是 <fs.Stats> 对象。
如果出现错误,err.code
将是常见系统错误之一。
不建议在调用 fs.open()
、fs.readFile()
或 fs.writeFile()
之前使用 fs.stat()
检查文件是否存在。
而是,用户代码应该直接打开/读取/写入文件,并在文件不可用时处理引发的错误。
要检查文件是否存在而不对其进行操作,建议使用 fs.access()
。
例如,给定以下目录结构:
- txtDir
-- file.txt
- app.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);
});
}
结果输出将类似于:
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.symlink(target, path[, type], callback)
#
target
<string> | <Buffer> | <URL>path
<string> | <Buffer> | <URL>type
<string> | <null> 默认值:null
callback
<Function>err
<Error>
创建名为 path
指向 target
的链接。
除了可能的异常之外,没有为完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX symlink(2)
文档。
type
参数仅在 Windows 上可用,在其他平台上被忽略。
可以设置为 'dir'
、'file'
或 'junction'
。
如果 type
参数不是字符串,则 Node.js 将自动检测 target
类型并使用 'file'
或 'dir'
。
如果 target
不存在,将使用 'file'
。
Windows 交接点要求目标路径是绝对路径。
使用 'junction'
时,target
参数将自动规范化为绝对路径。
相对目标是相对于链接的父目录。
import { symlink } from 'node:fs';
symlink('./mew', './mewtwo', callback);
上面的示例创建了符号链接 mewtwo
,其指向同一目录中的 mew
:
$ tree .
.
├── mew
└── mewtwo -> ./mew
fs.truncate(path[, len], callback)
#
path
<string> | <Buffer> | <URL>len
<integer> 默认值:0
callback
<Function>err
<Error> | <AggregateError>
截断文件。
除了可能的异常之外,没有为完成回调提供任何参数。
文件描述符也可以作为第一个参数传入。
在这种情况下,fs.ftruncate()
被调用。
import { truncate } from 'node:fs';
// 假设 'path/file.txt' 是普通文件。
truncate('path/file.txt', (err) => {
if (err) throw err;
console.log('path/file.txt was truncated');
});
const { truncate } = require('node:fs');
// 假设 'path/file.txt' 是普通文件。
truncate('path/file.txt', (err) => {
if (err) throw err;
console.log('path/file.txt was truncated');
});
不推荐传入文件描述符,并且可能会导致将来抛出错误。
有关更多详细信息,请参阅 POSIX truncate(2)
文档。
fs.unlink(path, callback)
#
path
<string> | <Buffer> | <URL>callback
<Function>err
<Error>
异步地删除文件或符号链接。 除了可能的异常之外,没有为完成回调提供任何参数。
import { unlink } from 'node:fs';
// 假设 'path/file.txt' 是普通文件。
unlink('path/file.txt', (err) => {
if (err) throw err;
console.log('path/file.txt was deleted');
});
fs.unlink()
不适用于目录,无论是空目录还是其他目录。
要删除目录,请使用 fs.rmdir()
。
有关更多详细信息,请参阅 POSIX unlink(2)
文档。
fs.unwatchFile(filename[, listener])
#
filename
<string> | <Buffer> | <URL>listener
<Function> 可选,先前使用fs.watchFile()
附加的监听器。
停止监视 filename
的变化。
如果指定了 listener
,则仅删除该特定监听器。
否则,所有监听器都将被删除,从而有效地停止监视 filename
。
使用未被监视的文件名调用 fs.unwatchFile()
是空操作,而不是错误。
使用 fs.watch()
比 fs.watchFile()
和 fs.unwatchFile()
更高效。
应尽可能使用 fs.watch()
而不是 fs.watchFile()
和 fs.unwatchFile()
。
fs.utimes(path, atime, mtime, callback)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>callback
<Function>err
<Error>
更改 path
引用的对象的文件系统时间戳。
atime
和 mtime
参数遵循以下规则:
- 值可以是代表 Unix 纪元时间的数字、
Date
、或数字字符串(例如'123456789.0'
)。 - 如果该值不能转换为数字,或者是
NaN
、Infinity
或-Infinity
,则会抛出Error
。
fs.watch(filename[, options][, listener])
#
filename
<string> | <Buffer> | <URL>options
<string> | <Object>persistent
<boolean> 指示只要正在监视文件,进程是否应继续运行。 默认值:true
。recursive
<boolean> 指示是应监视所有子目录,还是仅监视当前目录。 这在指定目录时适用,并且仅在受支持的平台上有效(请参见注意事项)。 默认值:false
。encoding
<string> 指定用于传给监听器的文件名的字符编码。 默认值:'utf8'
。signal
<AbortSignal> 允许使用中止信号关闭监视器。
listener
<Function> | <undefined> 默认值:undefined
- 返回: <fs.FSWatcher>
监视 filename
的变化,其中 filename
是文件或目录。
第二个参数是可选的。
如果 options
作为字符串提供,则它指定 encoding
。
否则 options
应作为对象传入。
监听器回调有两个参数 (eventType, filename)
。
eventType
是 'rename'
或 'change'
,filename
是触发事件的文件的名称。
在大多数平台上,只要目录中文件名出现或消失,就会触发 'rename'
。
监听器回调绑定到由 <fs.FSWatcher> 触发的 'change'
事件,但它与 eventType
的 'change'
值不同。
如果传入了 signal
,则中止相应的 AbortController 将关闭返回的 <fs.FSWatcher>。
注意事项#
fs.watch
API 跨平台并非 100% 一致,并且在某些情况下不可用。
递归选项仅在 macOS 和 Windows 上受支持。
当在不支持它的平台上使用该选项时,将抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM
异常。
在 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()
将无法运行并可能抛出异常。
例如,使用虚拟化软件(例如 Vagrant 或 Docker)时,在网络文件系统(NFS、SMB等)或主机文件系统上监视文件或目录可能不可靠,在某些情况下甚至是不可能的。
仍然可以使用 fs.watchFile()
,它使用 stat 轮询,但这种方法较慢且不太可靠。
索引节点#
在 Linux 和 macOS 系统上,fs.watch()
解析索引节点的路径并监视索引节点。
如果监视路径被删除并重新创建,则会为其分配一个新的索引节点。
监视将触发删除事件,但将继续监视原始索引节点。
不会发出新索引节点的事件。
这是预期的行为。
AIX 文件在文件的生命周期内保留相同的索引节点。 在 AIX 上保存和关闭监视文件将产生两个通知(一个用于添加新内容,另一个用于截断)。
文件名参数#
仅在 Linux、macOS、Windows 和 AIX 上支持在回调中提供 filename
参数。
即使在支持的平台上,也不能保证始终提供 filename
。
因此,不要假设回调中总是提供 filename
参数,如果它为 null
,则有一些回退逻辑。
import { watch } from 'node:fs';
watch('somedir', (eventType, filename) => {
console.log(`event type is: ${eventType}`);
if (filename) {
console.log(`filename provided: ${filename}`);
} else {
console.log('filename not provided');
}
});
fs.watchFile(filename[, options], listener)
#
filename
<string> | <Buffer> | <URL>options
<Object>listener
<Function>current
<fs.Stats>previous
<fs.Stats>
- 返回: <fs.StatWatcher>
监视 filename
的变化。
每次访问文件时都会调用回调 listener
。
可以省略 options
参数。
如果提供,它应该是一个对象。
options
对象可以包含名为 persistent
的布尔值,其指示当文件正在被监视时,进程是否应该继续运行。
options
对象可以指定 interval
属性,指示应该轮询目标的频率(以毫秒为单位)。
listener
具有两个参数,当前的统计对象和上一个统计对象:
import { watchFile } from 'node:fs';
watchFile('message.text', (curr, prev) => {
console.log(`the current mtime is: ${curr.mtime}`);
console.log(`the previous mtime was: ${prev.mtime}`);
});
这些统计对象是 fs.Stat
的实例。
如果 bigint
选项为 true
,则这些对象中的数值被指定为 BigInt
。
要在文件被修改(而不仅仅是访问)时得到通知,则需要比较 curr.mtimeMs
和 prev.mtimeMs
。
当 fs.watchFile
操作导致 ENOENT
错误时,它将调用监听器一次,且所有字段均清零(或者,对于日期,则为 Unix Epoch)。
如果文件是后来创建的,则将使用最新的统计对象再次调用监听器。
这是自 v0.10 以来的功能变化。
使用 fs.watch()
比 fs.watchFile
和 fs.unwatchFile
更高效。
应尽可能使用 fs.watch
而不是 fs.watchFile
和 fs.unwatchFile
。
当 fs.watchFile()
正在监视的文件消失并重新出现时,则第二个回调事件(文件的重新出现)中的 previous
的内容将与第一个回调事件(文件的消失)中的 previous
的内容相同。
这发生在:
- 文件被删除,然后恢复
- 文件被重命名,然后再次重命名回其原始名称
fs.write(fd, buffer, offset[, length[, position]], callback)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer> 默认值:0
length
<integer> 默认值:buffer.byteLength - offset
position
<integer> | <null> 默认值:null
callback
<Function>err
<Error>bytesWritten
<integer>buffer
<Buffer> | <TypedArray> | <DataView>
将 buffer
写入 fd
指定的文件。
offset
确定要写入的缓冲区部分,length
是整数,指定要写入的字节数。
position
指从文件开头数据应被写入的偏移量。
如果 typeof position !== 'number'
,则数据将写入当前位置。
参见 pwrite(2)
。
回调将提供三个参数 (err, bytesWritten, buffer)
,其中 bytesWritten
指定从 buffer
写入的字节数。
如果此方法作为其 util.promisify()
版本被调用,则返回具有 bytesWritten
和 buffer
属性的 Object
的 promise。
在同一个文件上多次使用 fs.write()
而不等待回调是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。 内核会忽略位置参数,并始终将数据追加到文件末尾。
fs.write(fd, buffer[, options], callback)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>options
<Object>callback
<Function>err
<Error>bytesWritten
<integer>buffer
<Buffer> | <TypedArray> | <DataView>
将 buffer
写入 fd
指定的文件。
与上面的 fs.write
函数类似,此版本采用可选的 options
对象。
如果未指定 options
对象,则默认使用上述值。
fs.write(fd, string[, position[, encoding]], callback)
#
fd
<integer>string
<string> | <Object>position
<integer> | <null> 默认值:null
encoding
<string> 默认值:'utf8'
callback
<Function>
将 string
写入 fd
指定的文件。
如果 string
不是字符串,或者不是具有自有的 toString
函数属性的对象,则会抛出异常。
position
指从文件开头数据应被写入的偏移量。
如果 typeof position !== 'number'
,则数据将写入当前位置。
参见 pwrite(2)
。
encoding
是预期的字符串编码。
回调将接收参数 (err, written, string)
,其中 written
指定传入的字符串需要被写入的字节数。
写入的字节数不一定与写入的字符串字符数相同。
参见 Buffer.byteLength
。
在同一个文件上多次使用 fs.write()
而不等待回调是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。 内核会忽略位置参数,并始终将数据追加到文件末尾。
在 Windows 上,如果文件描述符连接到控制台(例如 fd == 1
或 stdout
),则默认情况下无论使用何种编码,都无法正确呈现包含非 ASCII 字符的字符串。
通过使用 chcp 65001
命令更改激活的代码页,可以将控制台配置为可正确呈现 UTF-8。
有关更多详细信息,请参阅 chcp 文档。
fs.writeFile(file, data[, options], callback)
#
file
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符data
<string> | <Buffer> | <TypedArray> | <DataView> | <Object>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
mode
<integer> 默认值:0o666
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'w'
。signal
<AbortSignal> 允许中止正在进行的写入文件
callback
<Function>err
<Error> | <AggregateError>
当 file
是文件名时,将数据异步地写入文件,如果文件已存在则替换该文件。
data
可以是字符串或缓冲区。
当 file
是文件描述符时,其行为类似于直接调用 fs.write()
(推荐)。
请参阅以下有关使用文件描述符的说明。
如果 data
是缓冲区,则忽略 encoding
选项。
mode
选项仅影响新创建的文件。
有关详细信息,请参阅 fs.open()
。
如果 data
是普通的对象,则它必须具有自有的(不是继承的)toString
函数属性。
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
是字符串,则它指定编码:
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()
。
取消是"尽力而为"的,并且可能仍会写入一些数据。
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()
相同,例如:
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)
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer> | <null> 默认值:null
callback
<Function>err
<Error>bytesWritten
<integer>buffers
<ArrayBufferView[]>
使用 writev()
将 ArrayBufferView
数组写入 fd
指定的文件。
position
是该数据应写入的文件开头的偏移量。
如果 typeof position !== 'number'
,则数据将写入当前位置。
回调将被赋予三个参数:err
、bytesWritten
和 buffers
。
bytesWritten
是从 buffers
写入的字节数。
如果这个方法是 util.promisify()
的,它返回具有 bytesWritten
和 buffers
属性的 Object
的 promise。
在同一个文件上多次使用 fs.writev()
而不等待回调是不安全的。
对于这种情况,请使用 fs.createWriteStream()
。
在 Linux 上,以追加模式打开文件时,位置写入不起作用。 内核会忽略位置参数,并始终将数据追加到文件末尾。
同步的 API#
同步的 API 同步地执行所有操作,阻塞事件循环,直到操作完成或失败。
fs.accessSync(path[, mode])
#
同步地测试用户对 path
指定的文件或目录的权限。
mode
参数是可选的整数,指定要执行的可访问性检查。
mode
应该是值 fs.constants.F_OK
或由 fs.constants.R_OK
、fs.constants.W_OK
和 fs.constants.X_OK
中的任何一个(例如 fs.constants.W_OK | fs.constants.R_OK
)的按位或组成的掩码。
查看文件访问的常量以获取可能的 mode
值。
如果任何可访问性检查失败,将抛出 Error
。
否则,该方法将返回 undefined
。
import { accessSync, constants } from 'node:fs';
try {
accessSync('etc/passwd', constants.R_OK | constants.W_OK);
console.log('can read/write');
} catch (err) {
console.error('no access!');
}
fs.appendFileSync(path, data[, options])
#
path
<string> | <Buffer> | <URL> | <number> 文件名或文件描述符data
<string> | <Buffer>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
mode
<integer> 默认值:0o666
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'a'
。
同步地将数据追加到文件中,如果文件尚不存在则创建该文件。
data
可以是字符串或 <Buffer>。
mode
选项仅影响新创建的文件。
有关详细信息,请参阅 fs.open()
。
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
是字符串,则它指定编码:
import { appendFileSync } from 'node:fs';
appendFileSync('message.txt', 'data to append', 'utf8');
可以将 path
指定为已打开用于追加(使用 fs.open()
或 fs.openSync()
)的数字文件描述符。
文件描述符不会自动关闭。
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)
#
有关详细信息,请参阅此 API 的异步版本的文档:fs.chmod()
。
有关更多详细信息,请参阅 POSIX chmod(2)
文档。
fs.chownSync(path, uid, gid)
#
同步地更改文件的所有者和群组。
返回 undefined
。
这是 fs.chown()
的同步版本。
有关更多详细信息,请参阅 POSIX chown(2)
文档。
fs.closeSync(fd)
#
fd
<integer>
关闭文件描述符。
返回 undefined
。
通过任何其他 fs
操作对当前正在使用的任何文件描述符 (fd
) 调用 fs.closeSync()
,则可能会导致未定义的行为。
有关更多详细信息,请参阅 POSIX close(2)
文档。
fs.copyFileSync(src, dest[, mode])
#
src
<string> | <Buffer> | <URL> 要复制的源文件名dest
<string> | <Buffer> | <URL> 复制操作的目标文件名mode
<integer> 复制操作的修饰符。 默认值: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
: 复制操作将尝试创建写时复制引用链接。 如果平台不支持写时复制,则使用后备复制机制。fs.constants.COPYFILE_FICLONE_FORCE
: 复制操作将尝试创建写时复制引用链接。 如果平台不支持写时复制,则该操作将失败。
import { copyFileSync, constants } from 'node:fs';
// 默认情况下将创建或覆盖 destination.txt。
copyFileSync('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');
// 通过使用 COPYFILE_EXCL,如果 destination.txt 存在,则该操作将失败。
copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
fs.cpSync(src, dest[, options])
#
src
<string> | <URL> 要复制的源路径。dest
<string> | <URL> 要复制到的目标路径。options
<Object>dereference
<boolean> 取消引用符号链接。 默认值:false
。errorOnExist
<boolean> 当force
为false
且目标存在时,则抛出错误。 默认值:false
。filter
<Function> 过滤复制文件/目录的函数。 返回true
则复制条目,返回false
则忽略它。 默认值:undefined
force
<boolean> 覆盖现有的文件或目录。 如果将此设置为 false 并且目标存在,则复制操作将忽略错误。 使用errorOnExist
选项更改此行为。 默认值:true
。preserveTimestamps
<boolean> 当为true
时,则src
的时间戳将被保留。 默认值:false
。recursive
<boolean> 递归地复制目录 默认值:false
verbatimSymlinks
<boolean> 当为true
时,则符号链接的路径解析将被跳过。 默认值:false
将整个目录结构从 src
同步地复制到 dest
,包括子目录和文件。
当将目录复制到另一个目录时,不支持 globs,并且行为类似于 cp dir1/ dir2/
。
fs.existsSync(path)
#
如果路径存在则返回 true
,否则返回 false
。
有关详细信息,请参阅此 API 的异步版本的文档:fs.exists()
。
fs.exists()
已弃用,但 fs.existsSync()
不是。
fs.exists()
的 callback
参数接受与其他 Node.js 回调不一致的参数。
fs.existsSync()
不使用回调。
import { existsSync } from 'node:fs';
if (existsSync('/etc/passwd'))
console.log('The path exists.');
fs.fchmodSync(fd, mode)
#
设置文件的权限。
返回 undefined
。
有关更多详细信息,请参阅 POSIX fchmod(2)
文档。
fs.fchownSync(fd, uid, gid)
#
设置文件的所有者。
返回 undefined
。
有关更多详细信息,请参阅 POSIX fchown(2)
文档。
fs.fdatasyncSync(fd)
#
fd
<integer>
将与文件关联的所有当前排队的 I/O 操作强制为操作系统的同步 I/O 完成状态。
有关详细信息,请参阅 POSIX fdatasync(2)
文档。
返回 undefined
。
fs.fstatSync(fd[, options])
#
fd
<integer>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。
- 返回: <fs.Stats>
获取文件描述符的 <fs.Stats>。
有关更多详细信息,请参阅 POSIX fstat(2)
文档。
fs.fsyncSync(fd)
#
fd
<integer>
请求将打开文件描述符的所有数据刷新到存储设备。
具体实现是操作系统和设备特定的。
有关更多详细信息,请参考 POSIX fsync(2)
文档。
返回 undefined
。
fs.ftruncateSync(fd[, len])
#
截断文件描述符。
返回 undefined
。
有关详细信息,请参阅此 API 的异步版本的文档:fs.ftruncate()
。
fs.futimesSync(fd, atime, mtime)
#
fs.futimes()
的同步版本。
返回 undefined
。
fs.lchmodSync(path, mode)
#
更改符号链接的权限。
返回 undefined
。
此方法仅在 macOS 上实现。
有关更多详细信息,请参阅 POSIX lchmod(2)
文档。
fs.lchownSync(path, uid, gid)
#
设置路径的所有者。
返回 undefined
。
有关更多详细信息,请参阅 POSIX lchown(2)
文档。
fs.lutimesSync(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>
更改 path
引用的符号链接的文件系统时间戳。
返回 undefined
,或在参数不正确或操作失败时抛出异常。
这是 fs.lutimes()
的同步版本。
fs.linkSync(existingPath, newPath)
#
创建从 existingPath
到 newPath
的新链接。
有关更多详细信息,请参阅 POSIX link(2)
文档。
返回 undefined
。
fs.lstatSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。throwIfNoEntry
<boolean> 如果文件系统条目不存在,是否会抛出异常,而不是返回undefined
。 默认值:true
。
- 返回: <fs.Stats>
获取 path
引用的符号链接的 <fs.Stats>。
有关更多详细信息,请参阅 POSIX lstat(2)
文档。
fs.mkdirSync(path[, options])
#
同步地创建目录。
返回 undefined
或创建的第一个目录路径(如果 recursive
为 true
)。
这是 fs.mkdir()
的同步版本。
有关更多详细信息,请参阅 POSIX mkdir(2)
文档。
fs.mkdtempSync(prefix[, options])
#
返回创建的目录路径。
有关详细信息,请参阅此 API 的异步版本的文档:fs.mkdtemp()
。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定要使用的字符编码)的对象。
fs.opendirSync(path[, options])
#
同步地打开目录。
参见 opendir(3)
。
创建 <fs.Dir>,其中包含用于从目录读取和清理目录的所有进一步的函数。
encoding
选项设置在打开目录和随后的读取操作时 path
的编码。
fs.openSync(path[, flags[, mode]])
#
path
<string> | <Buffer> | <URL>flags
<string> | <number> 默认值:'r'
。 请参阅对文件系统flags
的支持。mode
<string> | <integer> 默认值:0o666
- 返回: <number>
返回表示文件描述符的整数。
有关详细信息,请参阅此 API 的异步版本的文档:fs.open()
。
fs.readdirSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>- 返回: <string[]> | <Buffer[]> | <fs.Dirent[]>
读取目录的内容。
有关更多详细信息,请参阅 POSIX readdir(3)
文档。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于返回的文件名的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的文件名将作为 <Buffer> 对象传入。
如果 options.withFileTypes
设置为 true
,则结果将包含 <fs.Dirent> 对象。
fs.readFileSync(path[, options])
#
path
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符options
<Object> | <string>encoding
<string> | <null> 默认值:null
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'r'
。
- 返回: <string> | <Buffer>
返回 path
的内容。
有关详细信息,请参阅此 API 的异步版本的文档:fs.readFile()
。
如果指定了 encoding
选项,则此函数返回字符串。
否则它返回缓冲区。
与 fs.readFile()
类似,当路径为目录时,fs.readFileSync()
的行为是特定于平台的。
import { readFileSync } from 'node:fs';
// macOS、Linux 和 Windows
readFileSync('<directory>');
// => [Error: EISDIR: illegal operation on a directory, read <directory>]
// FreeBSD
readFileSync('<directory>'); // => <data>
fs.readlinkSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
- 返回: <string> | <Buffer>
返回符号链接的字符串值。
有关更多详细信息,请参阅 POSIX readlink(2)
文档。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于返回的链接路径的字符编码)的对象。
如果将 encoding
设置为 'buffer'
,则返回的链接路径将作为 <Buffer> 对象传入。
fs.readSync(fd, buffer, offset, length[, position])
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer>length
<integer>position
<integer> | <bigint> | <null> 默认值:null
- 返回: <number>
返回 bytesRead
的数量。
有关详细信息,请参阅此 API 的异步版本的文档:fs.read()
。
fs.readSync(fd, buffer[, options])
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>options
<Object>- 返回: <number>
返回 bytesRead
的数量。
与上面的 fs.readSync
函数类似,此版本采用可选的 options
对象。
如果未指定 options
对象,则默认使用上述值。
有关详细信息,请参阅此 API 的异步版本的文档:fs.read()
。
fs.readvSync(fd, buffers[, position])
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer> | <null> 默认值:null
- 返回: <number> 读取的字节数。
有关详细信息,请参阅此 API 的异步版本的文档:fs.readv()
。
fs.realpathSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
- 返回: <string> | <Buffer>
返回解析的路径名。
有关详细信息,请参阅此 API 的异步版本的文档:fs.realpath()
。
fs.realpathSync.native(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
- 返回: <string> | <Buffer>
同步的 realpath(3)
。
仅支持可以转换为 UTF8 字符串的路径。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性(指定用于返回的路径的字符编码)的对象。
如果 encoding
设置为 'buffer'
,则返回的路径将作为 <Buffer> 对象传入。
在 Linux 上,将 Node.js 与 musl libc 链接时,必须将 procfs 文件系统挂载在 /proc
上,此函数才能起作用。
Glibc 没有此限制。
fs.renameSync(oldPath, newPath)
#
将文件从 oldPath
重命名为 newPath
。
返回 undefined
。
有关更多详细信息,请参阅 POSIX rename(2)
文档。
fs.rmdirSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,Node.js 将在每次尝试时以retryDelay
毫秒的线性退避等待时间重试该操作。 此选项表示重试次数。 如果recursive
选项不为true
,则忽略此选项。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归目录删除。 在递归模式下,操作将在失败时重试。 默认值:false
。 已弃用。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则忽略此选项。 默认值:100
。
同步的 rmdir(2)
。
返回 undefined
。
在文件(而不是目录)上使用 fs.rmdirSync()
,则在 Windows 上会导致 ENOENT
错误,在 POSIX 上会导致 ENOTDIR
错误。
要获得类似于 rm -rf
Unix 命令的行为,则使用具有选项 { recursive: true, force: true }
的 fs.rmSync()
。
fs.rmSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>force
<boolean> 当为true
时,如果path
不存在,则异常将被忽略。 默认值:false
。maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,Node.js 将在每次尝试时以retryDelay
毫秒的线性退避等待时间重试该操作。 此选项表示重试次数。 如果recursive
选项不为true
,则忽略此选项。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归目录删除。 在递归模式下,操作将在失败时重试。 默认值:false
。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则忽略此选项。 默认值:100
。
同步删除文件和目录(以标准 POSIX rm
实用工具为模型)。
返回 undefined
。
fs.statSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>bigint
<boolean> 返回的 <fs.Stats> 对象中的数值是否应为bigint
。 默认值:false
。throwIfNoEntry
<boolean> 如果文件系统条目不存在,是否会抛出异常,而不是返回undefined
。 默认值:true
。
- 返回: <fs.Stats>
获取路径的 <fs.Stats>。
fs.symlinkSync(target, path[, type])
#
target
<string> | <Buffer> | <URL>path
<string> | <Buffer> | <URL>type
<string> | <null> 默认值:null
返回 undefined
。
有关详细信息,请参阅此 API 的异步版本的文档:fs.symlink()
。
fs.truncateSync(path[, len])
#
截断文件。
返回 undefined
。
文件描述符也可以作为第一个参数传入。
在这种情况下,fs.ftruncateSync()
被调用。
不推荐传入文件描述符,并且可能会导致将来抛出错误。
fs.unlinkSync(path)
#
同步的 unlink(2)
。
返回 undefined
。
fs.utimesSync(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>
返回 undefined
。
有关详细信息,请参阅此 API 的异步版本的文档:fs.utimes()
。
fs.writeFileSync(file, data[, options])
#
file
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符data
<string> | <Buffer> | <TypedArray> | <DataView> | <Object>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
mode
<integer> 默认值:0o666
flag
<string> 请参阅对文件系统flags
的支持。 默认值:'w'
。
返回 undefined
。
如果 data
是普通的对象,则它必须具有自有的(不是继承的)toString
函数属性。
mode
选项仅影响新创建的文件。
有关详细信息,请参阅 fs.open()
。
有关详细信息,请参阅此 API 的异步版本的文档:fs.writeFile()
。
fs.writeSync(fd, buffer, offset[, length[, position]])
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer> 默认值:0
length
<integer> 默认值:buffer.byteLength - offset
position
<integer> | <null> 默认值:null
- 返回: <number> 写入的字节数。
有关详细信息,请参阅此 API 的异步版本的文档:fs.write(fd, buffer...)
。
fs.writeSync(fd, buffer[, options])
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>options
<Object>- 返回: <number> 写入的字节数。
有关详细信息,请参阅此 API 的异步版本的文档:fs.write(fd, buffer...)
。
fs.writeSync(fd, string[, position[, encoding]])
#
fd
<integer>string
<string>position
<integer> | <null> 默认值:null
encoding
<string> 默认值:'utf8'
- 返回: <number> 写入的字节数。
有关详细信息,请参阅此 API 的异步版本的文档:fs.write(fd, string...)
。
fs.writevSync(fd, buffers[, position])
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer> | <null> 默认值:null
- 返回: <number> 写入的字节数。
有关详细信息,请参阅此 API 的异步版本的文档:fs.writev()
。
公共对象#
公共对象由所有文件系统 API 变体(promise、回调和同步)共享。
fs.Dir
类#
表示目录流的类。
由 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
创建。
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()
#
- 返回: <Promise>
异步地关闭目录的底层资源句柄。 后续读取将导致错误。
返回将在资源关闭后解决的 promise。
dir.close(callback)
#
callback
<Function>err
<Error>
异步地关闭目录的底层资源句柄。 后续读取将导致错误。
资源句柄关闭后将调用 callback
。
dir.closeSync()
#
同步地关闭目录的底层资源句柄。 后续读取将导致错误。
dir.path
#
提供给 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
的此目录的只读路径。
dir.read()
#
- 返回: <Promise> 包含 <fs.Dirent> | <null>
通过 readdir(3)
异步地读取下一个目录条目作为 <fs.Dirent>。
返回 promise,其将使用 <fs.Dirent> 或 null
(如果读取不到更多的目录条目)解决。
此函数返回的目录条目没有操作系统底层目录机制提供的特定顺序。 迭代目录时添加或删除的条目可能不包括在迭代结果中。
dir.read(callback)
#
callback
<Function>err
<Error>dirent
<fs.Dirent> | <null>
通过 readdir(3)
异步地读取下一个目录条目作为 <fs.Dirent>。
读取完成后,将使用 <fs.Dirent> 或 null
(如果读取不到更多的目录条目)调用 callback
。
此函数返回的目录条目没有操作系统底层目录机制提供的特定顺序。 迭代目录时添加或删除的条目可能不包括在迭代结果中。
dir.readSync()
#
- 返回: <fs.Dirent> | <null>
同步地读取下一个目录条目作为 <fs.Dirent>。
有关更多详细信息,请参阅 POSIX readdir(3)
文档。
如果读取不到更多的目录条目,则将返回 null
。
此函数返回的目录条目没有操作系统底层目录机制提供的特定顺序。 迭代目录时添加或删除的条目可能不包括在迭代结果中。
dir[Symbol.asyncIterator]()
#
- 返回: <AsyncIterator> <fs.Dirent> 的
异步地遍历目录,直到读取了所有条目。
有关更多详细信息,请参考 POSIX readdir(3)
文档。
异步迭代器返回的条目始终是 <fs.Dirent>。
来自 dir.read()
的 null
情况是在内部处理的。
有关示例,请参见 <fs.Dir>。
此迭代器返回的目录条目没有操作系统底层目录机制提供的特定顺序。 迭代目录时添加或删除的条目可能不包括在迭代结果中。
fs.Dirent
类#
目录条目的表示,可以是目录中的文件或子目录,通过从 <fs.Dir> 读取返回。 目录条目是文件名和文件类型对的组合。
此外,当 fs.readdir()
或 fs.readdirSync()
在 withFileTypes
选项设置为 true
的情况下调用时,结果数组将填充 <fs.Dirent> 对象,而不是字符串或 <Buffer>。
dirent.isBlockDevice()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述块设备,则返回 true
。
dirent.isCharacterDevice()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述字符设备,则返回 true
。
dirent.isDirectory()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述文件系统目录,则返回 true
。
dirent.isFIFO()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述先进先出 (FIFO) 管道,则返回 true
。
dirent.isFile()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述常规文件,则返回 true
。
dirent.isSocket()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述套接字,则返回 true
。
dirent.isSymbolicLink()
#
- 返回: <boolean>
如果 <fs.Dirent> 对象描述符号链接,则返回 true
。
dirent.name
#
此 <fs.Dirent> 对象引用的文件名。
该值的类型由传给 fs.readdir()
或 fs.readdirSync()
的 options.encoding
决定。
fs.FSWatcher
类#
- 继承自 <EventEmitter>
成功调用 fs.watch()
方法将返回新的 <fs.FSWatcher> 对象。
每当修改指定的被监视文件时,所有 <fs.FSWatcher> 对象都会触发 'change'
事件。
'change'
事件#
当监视的目录或文件中的某些内容发生更改时触发。
在 fs.watch()
中查看更多详细信息。
根据操作系统支持,可能不提供 filename
参数。
如果提供了 filename
,如果 fs.watch()
在其 encoding
选项设置为 'buffer'
的情况下被调用,它将作为 <Buffer> 提供,否则 filename
将是 UTF-8 字符串。
import { watch } from 'node:fs';
// 通过 fs.watch() 监听器处理的示例
watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
if (filename) {
console.log(filename);
// 打印: <Buffer ...>
}
});
'close'
事件#
当监视器停止监视变化时触发。 关闭的 <fs.FSWatcher> 对象在事件句柄中不再可用。
'error'
事件#
error
<Error>
在监视文件时发生错误时触发。 出错的 <fs.FSWatcher> 对象在事件句柄中不再可用。
watcher.close()
#
停止监视给定 <fs.FSWatcher> 上的更改。 一旦停止,<fs.FSWatcher> 对象就不再可用。
watcher.ref()
#
- 返回: <fs.FSWatcher>
调用时,只要 <fs.FSWatcher> 处于活动状态,就请求 Node.js 事件循环不退出。
多次调用 watcher.ref()
将不起作用。
默认情况下,所有 <fs.FSWatcher> 对象都被“引用”,这使得通常不需要调用 watcher.ref()
除非之前已经调用过 watcher.unref()
。
watcher.unref()
#
- 返回: <fs.FSWatcher>
调用时,活动的 <fs.FSWatcher> 对象不需要 Node.js 事件循环保持活动状态。
如果没有其他活动保持事件循环运行,则进程可能会在调用 <fs.FSWatcher> 对象的回调之前退出。
多次调用 watcher.unref()
将不起作用。
fs.StatWatcher
类#
- 继承自 <EventEmitter>
成功调用 fs.watchFile()
方法将返回新的 <fs.StatWatcher> 对象。
watcher.ref()
#
- 返回: <fs.StatWatcher>
调用时,只要 <fs.StatWatcher> 处于活动状态,就请求 Node.js 事件循环不退出。
多次调用 watcher.ref()
将不起作用。
默认情况下,所有 <fs.StatWatcher> 对象都被“引用”,这使得通常不需要调用 watcher.ref()
除非之前已经调用过 watcher.unref()
。
watcher.unref()
#
- 返回: <fs.StatWatcher>
调用时,活动的 <fs.StatWatcher> 对象不需要 Node.js 事件循环保持活动状态。
如果没有其他活动保持事件循环运行,则进程可能会在调用 <fs.StatWatcher> 对象的回调之前退出。
多次调用 watcher.unref()
将不起作用。
fs.ReadStream
类#
- 继承自: <stream.Readable>
<fs.ReadStream> 的实例是使用 fs.createReadStream()
函数创建和返回的。
'close'
事件#
当 <fs.ReadStream> 的底层文件描述符已关闭时触发。
'open'
事件#
fd
<integer> <fs.ReadStream> 使用的整数文件描述符。
当 <fs.ReadStream> 的文件描述符被打开时触发。
'ready'
事件#
当 <fs.ReadStream> 准备好使用时触发。
'open'
后立即触发。
readStream.bytesRead
#
到目前为止已读取的字节数。
readStream.path
#
流正在读取的文件的路径,如 fs.createReadStream()
的第一个参数中所指定。
如果 path
作为字符串传入,则 readStream.path
将是字符串。
如果 path
作为 <Buffer> 传入,则 readStream.path
将是 <Buffer>。
如果指定了 fd
,则 readStream.path
将是 undefined
。
readStream.pending
#
如果底层文件尚未打开,即在触发 'ready'
事件之前,则此属性为 true
。
fs.Stats
类#
<fs.Stats> 对象提供有关文件的信息。
从 fs.stat()
、fs.lstat()
、fs.fstat()
及其同步对应对象返回的对象属于此类型。
如果传给这些方法的 options
中的 bigint
为 true,则数值将为 bigint
而不是 number
,并且该对象将包含额外的以 Ns
为后缀的纳秒精度属性。
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
版本:
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()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述块设备,则返回 true
。
stats.isCharacterDevice()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述字符设备,则返回 true
。
stats.isDirectory()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述文件系统目录,则返回 true
。
如果 <fs.Stats> 对象是从 fs.lstat()
获得的,则此方法将始终返回 false
。
这是因为 fs.lstat()
返回有关符号链接本身的信息,而不是它解析到的路径。
stats.isFIFO()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述先进先出 (FIFO) 管道,则返回 true
。
stats.isFile()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述常规文件,则返回 true
。
stats.isSocket()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述套接字,则返回 true
。
stats.isSymbolicLink()
#
- 返回: <boolean>
如果 <fs.Stats> 对象描述符号链接,则返回 true
。
此方法仅在使用 fs.lstat()
时有效。
stats.dev
#
包含文件的设备的数字标识符。
stats.ino
#
文件的文件系统特定的索引节点编号。
stats.mode
#
描述文件类型和模式的位字段。
stats.nlink
#
文件存在的硬链接数。
stats.uid
#
拥有文件的用户的数字用户标识符 (POSIX)。
stats.gid
#
拥有文件的群组的数字群组标识符 (POSIX)。
stats.rdev
#
如果文件代表设备,则为数字设备标识符。
stats.size
#
文件的大小(以字节为单位)。
如果底层文件系统不支持获取文件大小,则为 0
。
stats.blksize
#
i/o 操作的文件系统块大小。
stats.blocks
#
为此文件分配的块数。
stats.atimeMs
#
指示最后一次访问此文件的时间戳,以 POSIX Epoch 以来的毫秒数表示。
stats.mtimeMs
#
指示最后一次修改此文件的时间戳,以 POSIX Epoch 以来的毫秒数表示。
stats.ctimeMs
#
指示最后一次更改文件状态的时间戳,以 POSIX Epoch 以来的毫秒数表示。
stats.birthtimeMs
#
指示此文件创建时间的时间戳,以 POSIX Epoch 以来的毫秒数表示。
stats.atimeNs
#
仅在 bigint: true
传入到生成对象的方法中时出现。
指示最后一次访问此文件的时间戳,以 POSIX Epoch 以来的纳秒数表示。
stats.mtimeNs
#
仅在 bigint: true
传入到生成对象的方法中时出现。
指示最后一次修改此文件的时间戳,以 POSIX Epoch 以来的纳秒数表示。
stats.ctimeNs
#
仅在 bigint: true
传入到生成对象的方法中时出现。
指示最后一次更改文件状态的时间戳,以 POSIX Epoch 以来的纳秒数表示。
stats.birthtimeNs
#
仅在 bigint: true
传入到生成对象的方法中时出现。
指示此文件创建时间的时间戳,以 POSIX Epoch 以来的纳秒数表示。
stats.atime
#
指示最后一次访问此文件的时间戳。
stats.mtime
#
指示最后一次修改此文件的时间戳。
stats.ctime
#
指示最后一次更改文件状态的时间戳。
stats.birthtime
#
指示此文件创建时间的时间戳。
统计的时间值#
atimeMs
、mtimeMs
、ctimeMs
、birthtimeMs
属性是数值,以毫秒为单位保存相应的时间。
它们的精度是特定于平台的。
当 bigint: true
传给生成对象的方法时,属性将是长整数,否则它们将是数字。
atimeNs
、mtimeNs
、ctimeNs
、birthtimeNs
属性是以纳秒为单位保存相应时间的长整数。
它们仅在 bigint: true
传入到生成对象的方法中时出现。
它们的精度是特定于平台的。
atime
、mtime
、ctime
和 birthtime
是不同时间的 Date
对象替代表示。
Date
和数字值是不关联的。
分配新的数值或改变 Date
值不会反映在相应的替代表示中。
统计对象中的时间具有以下语义:
atime
"访问时间": 上次访问文件数据的时间。 由mknod(2)
、utimes(2)
和read(2)
系统调用更改。mtime
"修改时间": 上次修改文件数据的时间。 由mknod(2)
、utimes(2)
和write(2)
系统调用更改。ctime
"更改时间": 上次更改文件状态(修改索引节点数据)的时间。 由chmod(2)
、chown(2)
、link(2)
、mknod(2)
、rename(2)
、unlink(2)
、utimes(2)
、read(2)
和write(2)
系统调用更改。birthtime
"创建时间": 文件创建时间。 创建文件时设置一次。 在创建时间不可用的文件系统上,该字段可能改为保存ctime
或1970-01-01T00:00Z
(即 Unix 纪元时间戳0
)。 在这种情况下,该值可能大于atime
或mtime
。 在 Darwin 和其他 FreeBSD 变体上,如果使用utimes(2)
系统调用将atime
显式设置为比当前birthtime
更早的值,也会被设置。
在 Node.js 0.12 之前,ctime
是 Windows 系统上的 birthtime
。
从 0.12 开始,ctime
不是“创建时间”,在 Unix 系统上,它从来都不是。
fs.WriteStream
类#
<fs.WriteStream> 的实例是使用 fs.createWriteStream()
函数创建和返回的。
'close'
事件#
当 <fs.WriteStream> 的底层文件描述符已关闭时触发。
'open'
事件#
fd
<integer> <fs.WriteStream> 使用的整数文件描述符。
打开 <fs.WriteStream> 的文件时触发。
'ready'
事件#
当 <fs.WriteStream> 准备好使用时触发。
'open'
后立即触发。
writeStream.bytesWritten
#
到目前为止写入的字节数。 不包括仍在排队等待写入的数据。
writeStream.close([callback])
#
callback
<Function>err
<Error>
关闭 writeStream
。
可以选择接受一个回调,其将在 writeStream
关闭后执行。
writeStream.path
#
流正在写入的文件的路径,如 fs.createWriteStream()
的第一个参数中所指定。
如果 path
作为字符串传入,则 writeStream.path
将是字符串。
如果 path
作为 <Buffer> 传入,则 writeStream.path
将是 <Buffer>。
writeStream.pending
#
如果底层文件尚未打开,即在触发 'ready'
事件之前,则此属性为 true
。
fs.constants
#
返回一个包含文件系统操作常用常量的对象。
FS 常量#
以下常量由 fs.constants
和 fsPromises.constants
导出。
并非所有常量在每个操作系统上都可用;这对于 Windows 尤其重要,因为许多 POSIX 特定定义不可用。 对于便携式应用程序,建议在使用前检查它们的存在。
要使用多个常量,请使用按位或 |
运算符。
示例:
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 |
如果存在,复制操作将尝试创建写时复制引用链接。 如果底层平台不支持写时复制,则使用回退复制机制。 |
COPYFILE_FICLONE_FORCE |
如果存在,复制操作将尝试创建写时复制引用链接。 如果底层平台不支持写时复制,则操作将失败并显示错误。 |
这些定义在 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_APPEND
、O_CREAT
、O_EXCL
、O_RDONLY
、O_RDWR
、O_TRUNC
、O_WRONLY
和 UV_FS_O_FILEMAP
可用。
文件类型的常量#
以下常量旨在与 <fs.Stats> 对象的 mode
属性一起使用,以确定文件的类型。
常量 | 描述 |
---|---|
S_IFMT |
用于提取文件类型代码的位掩码。 |
S_IFREG |
常规文件的文件类型常量。 |
S_IFDIR |
目录的文件类型常量。 |
S_IFCHR |
面向字符的设备文件的文件类型常量。 |
S_IFBLK |
面向块的设备文件的文件类型常量。 |
S_IFIFO |
FIFO/管道的文件类型常量。 |
S_IFLNK |
符号链接的文件类型常量。 |
S_IFSOCK |
套接字的文件类型常量。 |
在 Windows 上,只有 S_IFCHR
、S_IFDIR
、S_IFLNK
、S_IFMT
和 S_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_IRUSR
和 S_IWUSR
可用。
注意事项#
回调与基于 promise 的操作的顺序#
因为它们是由底层线程池异步地执行,所以当使用回调或基于 promise 的方法时无法保证顺序。
例如,以下内容容易出错,因为 fs.stat()
操作可能会在 fs.rename()
操作之前完成:
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)}`);
});
通过在调用另一个之前等待前一个的结果来正确地排序操作,这是很重要的:
import { rename, stat } from 'node:fs/promises';
const from = '/tmp/hello';
const to = '/tmp/world';
try {
await rename(from, to);
const stats = await stat(to);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
const { rename, stat } = require('node:fs/promises');
(async function(from, to) {
try {
await rename(from, to);
const stats = await stat(to);
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()
操作的回调中。
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)}`);
});
});
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 上使用绝对路径的示例:
import { open } from 'node:fs/promises';
let fd;
try {
fd = await open('/open/some/file.txt', 'r');
// 对文件做一些事情
} finally {
await fd.close();
}
在 POSIX 上使用相对路径的示例(相对于 process.cwd()
):
import { open } from 'node:fs/promises';
let fd;
try {
fd = await open('file.txt', 'r');
// 对文件做一些事情
} finally {
await fd.close();
}
文件 URL 路径#
对于大多数 node:fs
模块函数,path
或 filename
参数可以作为使用 file:
协议的 <URL> 对象传入。
import { readFileSync } from 'node:fs';
readFileSync(new URL('file:///tmp/hello'));
file:
URL 始终是绝对路径。
平台特定的注意事项#
在 Windows 上,带有主机名的 file:
<URL> 转换为 UNC 路径,而带有驱动器号的 file:
<URL> 则转换为本地绝对路径。
没有主机名和驱动器号的 file:
<URL> 将导致错误:
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]: File URL path must be absolute
带有驱动器号的 file:
<URL> 必须在驱动器号之后使用 :
作为分隔符。
使用其他分隔符会导致错误。
在所有其他平台上,不支持带有主机名的 file:
<URL> 并且会导致错误:
import { readFileSync } from 'node:fs';
// 在其他平台上:
// - 不支持带有主机名的 WHATWG 文件 URL
// file://hostname/p/a/t/h/file => throw!
readFileSync(new URL('file://hostname/p/a/t/h/file'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
// - WHATWG 文件 URL 转换为绝对路径
// file:///tmp/hello => /tmp/hello
readFileSync(new URL('file:///tmp/hello'));
具有编码斜杠字符的 file:
<URL> 在所有平台上都将导致错误:
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]: File URL path must not include encoded
\ or / characters */
// 在 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]: File URL path must not include encoded
/ characters */
在 Windows 上,带有编码反斜杠的 file:
<URL> 将导致错误:
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]: File URL path must not include encoded
\ or / characters */
Buffer 路径#
使用 <Buffer> 指定的路径主要用于将文件路径视为不透明字节序列的某些 POSIX 操作系统。 在此类系统上,单个文件路径可能包含使用多种字符编码的子序列。 与字符串路径一样,<Buffer> 路径可以是相对的或绝对的:
在 POSIX 上使用绝对路径的示例:
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()
方法打开一个文件并分配一个新的文件描述符。
分配后,文件描述符可用于从文件读取数据、向文件写入数据或请求有关文件的信息。
操作系统限制在任何给定时间可能打开的文件描述符的数量,因此在操作完成时关闭描述符至关重要。 否则将导致内存泄漏,最终导致应用程序崩溃。
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;
}
// 使用统计
closeFd(fd);
});
} catch (err) {
closeFd(fd);
throw err;
}
});
基于 promise 的 API 使用 <FileHandle> 对象代替数字文件描述符。 这些对象由系统更好地管理,以确保资源不泄漏。 但是,仍然需要在操作完成时关闭它们:
import { open } from 'node:fs/promises';
let file;
try {
file = await open('/open/some/file.txt', 'r');
const stat = await file.stat();
// 使用统计
} finally {
await file.close();
}
线程池的使用#
所有基于回调和 promise 的文件系统 API(fs.FSWatcher()
除外)都使用 libuv 的线程池。
这可能会对某些应用程序产生令人惊讶的负面性能影响。
有关更多信息,请参阅 UV_THREADPOOL_SIZE
文档。
文件系统标志#
以下标志在 flag
选项接受字符串的任何地方可用。
-
'a'
: 打开文件进行追加。 如果文件不存在,则创建该文件。 -
'ax'
: 类似于'a'
但如果路径存在则失败。 -
'a+'
: 打开文件进行读取和追加。 如果文件不存在,则创建该文件。 -
'ax+'
: 类似于'a+'
但如果路径存在则失败。 -
'as'
: 以同步模式打开文件进行追加。 如果文件不存在,则创建该文件。 -
'as+'
: 以同步模式打开文件进行读取和追加。 如果文件不存在,则创建该文件。 -
'r'
: 打开文件进行读取。 如果文件不存在,则会发生异常。 -
'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
。
// 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()
可用于重置文件内容。