- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲(Buffer)
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入 Node环境
- 子进程(Child processes)
- 集群(Cluster)
- 命令行选项
- 控制台(Console)
- 核心包(Corepack)
- 加密(Crypto)
- 调试器(Debugger)
- 已弃用的 API
- 诊断通道(Diagnostics Channel)
- 域名系统(DNS)
- 域(Domain)
- 错误(Errors)
- 事件(Events)
- 文件系统(File system)
- 全局变量(Globals)
- HTTP
- HTTP/2
- HTTPS
- 检查器(Inspector)
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:packages 模块
- 网络(Net)
- 系统(OS)
- 路径(Path)
- 性能挂钩(Performance hooks)
- 性能挂钩(Permissions)
- 进程(Process)
- Punycode 国际化域名编码
- 查询字符串(Query strings)
- 命令行库(Readline)
- REPL 交互式编程环境
- 诊断报告
- 单个可执行应用程序
- Stream 流
- 字符串解码器
- 单元测试
- 定时器(Timers)
- 传输层安全/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用程序
- V8
- 虚拟机
- WebAssembly
- Web加密 API(Web Crypto API)
- 网络流 API(Web Streams API)
- 工作线程(Worker threads)
- zlib
Node.js v18.18.2 文档
- Node.js v18.18.2
-
►
目录
- 文件系统
- 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.readableWebStream(options)
filehandle.readFile(options)
filehandle.readLines([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])
filehandle[Symbol.asyncDispose]()
- 事件:
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.statfs(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
- 类:
- 回调接口
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.statfs(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.statfsSync(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])
- Common Objects
- Class:
fs.Dir
- Class:
fs.Dirent
- Class:
fs.FSWatcher
- Class:
fs.StatWatcher
- Class:
fs.ReadStream
- Class:
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
- Stat time values
- Class:
fs.StatFs
- Class:
fs.WriteStream
fs.constants
- Class:
- Notes
- 文件系统
-
►
索引
- Assertion testing
- Asynchronous context tracking
- Async hooks
- Buffer
- C++ addons
- C/C++ addons with Node-API
- C++ embedder API
- Child processes
- Cluster
- Command-line options
- Console
- Corepack
- Crypto
- Debugger
- Deprecated APIs
- Diagnostics Channel
- DNS
- Domain
- Errors
- Events
- File system
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules: CommonJS modules
- Modules: ECMAScript modules
- Modules:
node:module
API - Modules: Packages
- Net
- 系统(OS)
- 路径(Path)
- Performance hooks
- Permissions
- 进程(Process)
- Punycode
- Query strings
- 命令行库(Readline)
- REPL 交互式编程环境
- Report
- Single executable applications
- Stream
- String decoder
- Test runner
- Timers
- TLS/SSL
- Trace events
- TTY
- UDP/datagram
- URL
- Utilities
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- Worker threads
- Zlib
- ► 其他版本
- ► 选项
目录
- 文件系统
- 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.readableWebStream(options)
filehandle.readFile(options)
filehandle.readLines([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])
filehandle[Symbol.asyncDispose]()
- 事件:
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.statfs(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
- 类:
- 回调接口
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.statfs(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.statfsSync(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.StatFs
- 类:
fs.WriteStream
fs.constants
- 类:
- 注意
文件系统#
源代码: 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 模块 (ESM) 进行访问。
Promise 示例#
基于 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) {
// handle the error
}
const { unlinkSync } = require('node:fs');
try {
unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');
} catch (err) {
// handle the error
}
Promise API#
fs/promises
API提供返回 Promise 的异步文件系统方法。
Promise API 使用底层 Node.js 线程池在事件循环线程外执行文件系统操作。这些操作不是同步的或线程安全的。对同一文件执行多个并发修改时必须小心,否则可能会发生数据损坏。
类:FileHandle
#
<FileHandle>对象是数字文件描述符的对象包装器。
<FileHandle>对象的实例由fsPromises.open()
方法创建
。
所有<FileHandle>对象都是<EventEmitter>。
如果<FileHandle>未使用filehandle.close()
方法关闭,它将尝试自动关闭文件描述符并发出进程警告,有助于防止内存泄漏。请不要依赖此行为,因为它可能不可靠并且文件可能无法关闭。相反,始终显式关闭<FileHandle>。Node.js 将来可能会改变这种行为。
事件:'close'
#
当<FileHandle>已关闭且无法再使用时,会发出'close'
事件。
filehandle.appendFile(data[, options])
#
data
<字符串> | <缓冲区> | <类型化数组> | <数据视图> | <异步迭代> | <可迭代> | <流>options
<对象> | <字符串>- 返回:<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
<对象>- 返回:<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');
// Create a stream from some character device.
const stream = fd.createReadStream();
setTimeout(() => {
stream.close(); // This may not close the stream.
// Artificially marking end-of-stream, as if the underlying resource had
// indicated end-of-file by itself, allows the stream to close.
// This does not cancel pending read operations, and if there is such an
// operation, the process may still not be able to exit successfully
// until it finishes.
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
<对象>- 返回:<fs.WriteStream>
options
还可以包含start
选项,以允许在文件开头之后的某个位置写入数据,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 范围内。修改文件而不是替换它可能需要将flags
open
选项设置为r+
而不是默认的r
。encoding
可以是<Buffer>接受的任何一个。
如果'error'
或'finish'
上的 autoClose
设置为 true(默认行为),
文件描述符将自动关闭。如果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
<缓冲区> | <类型化数组> | <DataView>将填充读取的文件数据的缓冲区。offset
<integer>缓冲区中开始填充的位置。length
<整数>要读取的字节数。position
<整数> | <null>开始从文件读取数据的位置。如果为null
,将从当前文件位置读取数据,并更新该位置。如果position
是整数,则当前文件位置将保持不变。- 返回:<Promise>成功后,使用具有两个属性的对象实现:
bytesRead
<整数>读取的字节数buffer
<缓冲区> | <类型化数组> | <DataView>对传入的buffer
参数的引用。
从文件中读取数据并将其存储在给定的缓冲区中。
如果文件没有同时修改,则当读取的字节数为零时到达文件结尾。
filehandle.read([options])
#
options
<对象>- 返回:<Promise>成功后,使用具有两个属性的对象实现:
bytesRead
<整数>读取的字节数buffer
<缓冲区> | <类型化数组> | <DataView>对传入的buffer
参数的引用。
从文件中读取数据并将其存储在给定的缓冲区中。
如果文件没有同时修改,则当读取的字节数为零时到达文件结尾。
filehandle.read(buffer[, options])
#
buffer
<缓冲区> | <类型化数组> | <DataView>将填充读取的文件数据的缓冲区。options
<对象>- 返回:<Promise>成功后,使用具有两个属性的对象实现:
bytesRead
<整数>读取的字节数buffer
<缓冲区> | <类型化数组> | <DataView>对传入的buffer
参数的引用。
从文件中读取数据并将其存储在给定的缓冲区中。
如果文件没有同时修改,则当读取的字节数为零时到达文件结尾。
filehandle.readableWebStream(options)
#
-
options
<对象>type
<字符串> | <undefined>是否打开普通流或'bytes'
流。 默认值:undefined
-
返回:<可读流>
返回可用于读取文件数据的ReadableStream
。
如果多次调用此方法或在FileHandle
关闭或关闭后调用此方法,将会引发错误。
import {
open,
} from 'node:fs/promises';
const file = await open('./some/file/to/read');
for await (const chunk of file.readableWebStream())
console.log(chunk);
await file.close();
const {
open,
} = require('node:fs/promises');
(async () => {
const file = await open('./some/file/to/read');
for await (const chunk of file.readableWebStream())
console.log(chunk);
await file.close();
})();
虽然ReadableStream
会完成读取文件,但它不会自动关闭FileHandle
。用户代码仍必须调用
fileHandle.close()
方法。
filehandle.readFile(options)
#
options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:null
signal
<AbortSignal>允许中止正在进行的 readFile
- 返回:<Promise>成功读取文件内容后实现。如果未指定编码(使用
options.encoding
),则数据将作为<Buffer>对象返回。否则,数据将是一个字符串。
异步读取文件的全部内容。
如果options
是字符串,则它指定encoding
。
<FileHandle>必须支持读取。
如果对文件句柄进行
一次或多次filehandle.read()
调用,然后进行filehandle.readFile()
调用,则将从当前位置读取数据,直到文件末尾。它并不总是从文件的开头读取。
filehandle.readLines([options])
#
options
<对象>- 返回:<readline.InterfaceConstructor>
创建readline
接口并流式传输文件的便捷方法。请参阅filehandle.createReadStream()
了解选项。
import { open } from 'node:fs/promises';
const file = await open('./some/file/to/read');
for await (const line of file.readLines()) {
console.log(line);
}
const { open } = require('node:fs/promises');
(async () => {
const file = await open('./some/file/to/read');
for await (const line of file.readLines()) {
console.log(line);
}
})();
filehandle.readv(buffers[, position])
#
buffers
<缓冲区[]> | <TypedArray[]> | <数据视图[]>position
<整数> | <null>距应读取数据的文件开头的偏移量。如果position
不是number
,则将从当前位置读取数据。默认值:null
- 返回:<Promise>成功后实现包含两个属性的对象:
bytesRead
<integer>读取的字节数buffers
<缓冲区[]> | <TypedArray[]> | <DataView[]>属性包含对buffers
输入的引用。
从文件读取并写入<ArrayBufferView>数组
filehandle.stat([options])
#
options
<对象>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
<缓冲区> | <类型化数组> | <数据视图>offset
<integer>buffer
内要写入的数据开始的起始位置。length
<integer>从buffer
写入的字节数。默认值:buffer.byteLength - offset
position
<整数> | <null>距文件开头的偏移量,应写入buffer
中的数据。如果position
不是number
,则数据将写入当前位置。 有关更多详细信息,请参阅 POSIXpwrite(2)
文档。默认值:null
- 返回:< Promise >
将buffer
写入文件。
该 Promise 通过包含两个属性的对象来解决:
bytesWritten
<integer>写入的字节数buffer
<缓冲区> | <类型化数组> | <DataView>对buffer
写入的引用 。
在同一个文件上多次使用filehandle.write()
而不等待 Promise 得到解决(或拒绝)是不安全的。对于这种情况,请使用filehandle.createWriteStream()
。
在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核忽略位置参数并始终将数据附加到文件末尾。
filehandle.write(buffer[, options])
#
buffer
<缓冲区> | <类型化数组> | <数据视图>options
<对象>- 返回:< Promise >
将buffer
写入文件。
与上面的filehandle.write
函数类似,此版本采用可选的options
对象。如果没有指定options
对象,它将默认使用上述值。
filehandle.write(string[, position[, encoding]])
#
string
<字符串>position
<整数> | <null>应写入string
数据的距文件开头的偏移量。如果position
不是number
,数据将写入当前位置。 有关更多详细信息,请参阅 POSIXpwrite(2)
文档。默认值:null
encoding
<string>预期的字符串编码。默认值:'utf8'
- 返回:< Promise >
将string
写入文件。如果string
不是字符串,则 Promise 将被拒绝并出现错误。
该 Promise 通过包含两个属性的对象来解决:
bytesWritten
<integer>写入的字节数buffer
<string>对写入的string
的引用。
在同一个文件上多次使用filehandle.write()
而不等待 Promise 得到解决(或拒绝)是不安全的。对于这种情况,请使用filehandle.createWriteStream()
。
在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核忽略位置参数并始终将数据附加到文件末尾。
filehandle.writeFile(data, options)
#
异步将数据写入文件,如果文件已存在则替换该文件。
data
可以是字符串、缓冲区、<AsyncIterable>或<Iterable>对象。一旦成功, Promise 就得到解决,没有任何争议。
如果options
是字符串,则它指定encoding
。
<FileHandle>必须支持写入。
在同一个文件上多次使用filehandle.writeFile()
而不等待 Promise 得到解决(或拒绝)是不安全的。
如果对文件句柄进行
一次或多次filehandle.write()
调用,然后进行filehandle.writeFile()
调用,则数据将从当前位置写入到文件末尾。它并不总是从文件的开头写入。
filehandle.writev(buffers[, position])
#
buffers
<缓冲区[]> | <TypedArray[]> | <数据视图[]>position
<整数> | <null>应写入buffers
数据的距文件开头的偏移量。如果position
不是number
,数据将写入当前位置。默认值:null
- 返回:< Promise >
将<ArrayBufferView>数组写入文件。
该 Promise 通过包含两个属性的对象来解决:
bytesWritten
<integer>写入的字节数buffers
<缓冲区[]> | <TypedArray[]> | <DataView[]>对buffers
输入的引用 。
在同一个文件上多次调用writev()
而不等待 Promise 得到解决(或拒绝)是不安全的。
在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核忽略位置参数并始终将数据附加到文件末尾。
filehandle[Symbol.asyncDispose]()
#
filehandle.close()
的别名。
fsPromises.access(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
的可能值。
如果可访问性检查成功,则 Promise 将被解决,但没有任何价值。如果任何可访问性检查失败,则 Promise 将被拒绝并返回<Error>对象。以下示例检查当前进程是否可以读取和写入文件
/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
<字符串> | <缓冲区> | <网址> | <FileHandle>文件名或<FileHandle>data
<字符串> | <缓冲区>options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:'utf8'
mode
<整数> 默认值:0o666
flag
<string>查看文件系统的支持flags
。默认值:'a'
。
- 返回:<Promise>成功后,执行
undefined
。
将数据异步附加到文件,如果文件尚不存在则创建该文件。data
可以是字符串或<Buffer>。
如果options
是字符串,则它指定encoding
。
mode
选项仅影响新创建的文件。请参阅fs.open()
了解更多详情。
path
可以指定为已打开用于追加的<FileHandle> (使用fsPromises.open()
)。
fsPromises.chmod(path, mode)
#
更改文件的权限。
fsPromises.chown(path, uid, gid)
#
更改文件的所有权。
fsPromises.copyFile(src, dest[, mode])
#
src
<字符串> | <缓冲区> | <URL>要复制的源文件名dest
<字符串> | <缓冲区> | <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.error('The file could not be copied');
}
// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
try {
await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
console.log('source.txt was copied to destination.txt');
} catch {
console.error('The file could not be copied');
}
fsPromises.cp(src, dest[, options])
#
src
<字符串> | <URL>要复制的源路径。dest
<字符串> | <URL>要复制到的目标路径。options
<对象>dereference
<boolean>取消引用符号链接。默认值:false
。errorOnExist
<boolean>当force
为false
且目标存在时,抛出错误。默认值:false
。filter
<Function>过滤复制文件/目录的函数。返回true
复制该项目,返回false
忽略它。还可以返回 解析为true
或false
的Promise
默认值:undefined
。src
<string>要复制的源路径。dest
<string>要复制到的目标路径。- 返回:<布尔值> | < Promise >
force
<boolean>覆盖现有文件或目录。如果您将其设置为 false 并且目标存在,则复制操作将忽略错误。使用errorOnExist
选项更改此行为。 默认值:true
。mode
<integer>用于复制操作的修饰符。默认值:0
。请参阅fsPromises.copyFile()
的mode
标志。preserveTimestamps
<boolean>何时保留src
的true
时间戳。默认值:false
。recursive
<boolean>递归复制目录默认值:false
verbatimSymlinks
<boolean>当true
时,将跳过符号链接的路径解析。默认值:false
- 返回:<Promise>成功后,将执行
undefined
。
将整个目录结构从src
异步复制到dest
,包括子目录和文件。
将目录复制到另一个目录时,不支持 glob,并且行为类似于cp dir1/ dir2/
。
fsPromises.lchmod(path, mode)
#
更改符号链接的权限。
该方法仅在 macOS 上实现。
fsPromises.lchown(path, uid, gid)
#
更改符号链接的所有权。
fsPromises.lutimes(path, atime, mtime)
#
path
<字符串> | <缓冲区> | <网址>atime
<数字> | <字符串> | <日期>mtime
<数字> | <字符串> | <日期>- 返回:<Promise>成功后, 将执行
undefined
。
以与fsPromises.utimes()
相同的方式更改文件的访问和修改时间
,不同之处在于,如果路径引用符号链接,则不会取消引用该链接:而是符号链接的时间戳本身都改变了。
fsPromises.link(existingPath, newPath)
#
创建从existingPath
到newPath
的新链接。有关更多详细信息,请参阅 POSIX
link(2)
文档。
fsPromises.lstat(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。
- 返回:<Promise> 满足给定符号链接
path
的<fs.Stats>对象。
等价于fsPromises.stat()
,除非path
引用符号链接,在这种情况下,链接本身被统计,而不是它所引用的文件。有关更多详细信息,请参阅 POSIX lstat(2)
文档。
fsPromises.mkdir(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象> | <整数>- 返回:<Promise>成功后,如果
recursive
为false
,则满足undefined
,或者如果recursive
为true
,则满足创建的第一个目录路径。
异步创建目录。
可选的options
参数可以是指定mode
(权限和粘性位)的整数,也可以是具有mode
属性和recursive
的对象
属性指示是否应创建父目录。仅当recursive
为
false时,当path
是存在的目录时调用fsPromises.mkdir()
才会导致拒绝。
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 { 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
<字符串>options
<字符串> | <对象>encoding
<字符串> 默认值:'utf8'
- 返回:<Promise> 使用包含新创建的临时目录的文件系统路径的字符串来实现。
创建一个唯一的临时目录。通过将六个随机字符附加到提供的prefix
末尾来生成唯一的目录名称。由于平台不一致,请避免在prefix
中尾随 X
字符。某些平台(尤其是 BSD)可以返回六个以上的随机字符,并用随机字符替换prefix
中的尾随 X
字符。
可选的options
参数可以是指定编码的字符串,也可以是具有指定要使用的字符编码的encoding
属性的对象。
import { mkdtemp } from 'node:fs/promises';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
try {
await mkdtemp(join(tmpdir(), 'foo-'));
} catch (err) {
console.error(err);
}
fsPromises.mkdtemp()
方法会将随机选择的六个字符直接附加到prefix
字符串中。例如,给定目录
/tmp
,如果目的是在 /tmp
中创建临时目录,则
prefix
必须以尾随平台特定的路径分隔符结尾(require('node:path').sep
)。
fsPromises.open(path, flags[, mode])
#
path
<字符串> | <缓冲区> | <网址>flags
<字符串> | <number>查看文件系统flags
的支持。 默认值:'r'
。mode
<字符串> | <integer>如果创建文件,则设置文件模式(权限和粘性位)。默认值:0o666
(可读可写)- 返回:<Promise>通过<FileHandle>对象实现。
打开<FileHandle>。
有关更多详细信息,请参阅 POSIX open(2)
文档。
一些字符 ( < > : " / \ | ? *
) 在 Windows 下是保留的,如命名文件、路径和命名空间中所述。在 NTFS 下,如果文件名包含冒号,Node.js 将打开文件系统流,如
本 MSDN 页面所述。
fsPromises.opendir(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>encoding
<字符串> | <null> 默认值:'utf8'
bufferSize
<number>从目录读取时内部缓冲的目录条目数。值越高,性能越好,但内存使用率越高。默认值:32
recursive
<boolean>解析的Dir
将是一个 包含所有子文件和目录的<AsyncIterable> 。默认值:false
- 返回:<Promise> 通过<fs.Dir>实现。
异步打开目录进行迭代扫描。有关更多详细信息,请参阅 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])
#
读取目录的内容。
可选的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
<字符串> | <缓冲区> | <网址> | <FileHandle>文件名或FileHandle
options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:null
flag
<string>查看文件系统的支持flags
。默认值:'r'
。signal
<AbortSignal>允许中止正在进行的 readFile
- 返回:<Promise> 履行文件的内容。
异步读取文件的全部内容。
如果未指定编码(使用options.encoding
),则数据将作为<Buffer>对象返回。否则,数据将是一个字符串。
如果options
是字符串,则它指定编码。
当path
是目录时,fsPromises.readFile()
的行为是特定于平台的。在 macOS、Linux 和 Windows 上,promise 将被拒绝并出现错误。在 FreeBSD 上,将返回目录内容的表示形式。
读取位于运行代码同一目录中的package.json
文件的示例:
import { readFile } from 'node:fs/promises';
try {
const filePath = new URL('./package.json', import.meta.url);
const contents = await readFile(filePath, { encoding: 'utf8' });
console.log(contents);
} catch (err) {
console.error(err.message);
}
const { readFile } = require('node:fs/promises');
const { resolve } = require('node:path');
async function logFile() {
try {
const filePath = resolve('./package.json');
const contents = await readFile(filePath, { encoding: 'utf8' });
console.log(contents);
} catch (err) {
console.error(err.message);
}
}
logFile();
可以使用<AbortSignal>中止正在进行的readFile
。如果请求被中止,则返回的 Promise 将被拒绝并显示AbortError
:
import { readFile } from 'node:fs/promises';
try {
const controller = new AbortController();
const { signal } = controller;
const promise = readFile(fileName, { signal });
// Abort the request before the promise settles.
controller.abort();
await promise;
} catch (err) {
// When a request is aborted - err is an AbortError
console.error(err);
}
中止正在进行的请求不会中止单个操作系统请求,而是中止内部缓冲fs.readFile
的执行。
任何指定的<FileHandle>都必须支持读取。
fsPromises.readlink(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<字符串> | <对象>encoding
<字符串> 默认:'utf8'
- 返回:<Promise>成功后,将履行
linkString
。
读取path
引用的符号链接的内容。有关更多详细信息,请参阅 POSIX
readlink(2)
文档。成功后, Promise 将通过
linkString
解决。
可选的options
参数可以是指定编码的字符串,也可以是具有encoding
属性的对象,该属性指定用于返回的链接路径的字符编码。如果encoding
设置为'buffer'
,则返回的链接路径将作为<Buffer>对象传递。
fsPromises.realpath(path[, options])
#
使用与 fs.realpath.native()
函数相同的语义
确定 path
的实际位置。
仅支持可转换为 UTF8 字符串的路径。
可选的options
参数可以是指定编码的字符串,也可以是具有encoding
属性的对象,指定用于路径的字符编码。如果encoding
设置为'buffer'
,则返回的路径将作为<Buffer>对象传递。
在 Linux 上,当 Node.js 与 musl libc 链接时,必须将 procfs 文件系统安装在/proc
上才能使此功能正常工作。Glibc 没有这个限制。
fsPromises.rename(oldPath, newPath)
#
将oldPath
重命名为newPath
。
fsPromises.rmdir(path[, options])
#
删除由path
标识的目录。
在文件(而不是目录)上使用fsPromises.rmdir()
会导致 Promise 被拒绝,并在 Windows 上出现ENOENT
错误,在 POSIX 上出现 ENOTDIR
错误。
要获得类似于rm -rf
Unix 命令的行为,请使用
带有选项{ recursive: true, force: true }
的fsPromises.rm()
。
fsPromises.rm(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>force
<boolean>当true
时,如果path
不存在,则异常将被忽略。默认值:false
。maxRetries
<整数>如果是EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
遇到错误时,Node.js 将重试该操作,每次尝试都会延长retryDelay
毫秒的线性退避等待时间。该选项代表重试次数。如果recursive
选项不是true
,则忽略此选项。默认值:0
。recursive
<boolean>如果为true
,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值:false
。retryDelay
<整数>两次重试之间等待的时间(以毫秒为单位)。如果recursive
选项不是true
,则忽略此选项。 默认值:100
。
- 返回:<Promise>成功后,将执行
undefined
。
删除文件和目录(以标准 POSIX rm
实用程序为模型)。
fsPromises.stat(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。
- 返回:<Promise> 满足给定
path
的<fs.Stats>对象。
fsPromises.statfs(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.StatFs>对象中的数值是否 应为bigint
。默认值:false
。
- 返回:<Promise>满足给定
path
的<fs.StatFs>对象。
fsPromises.symlink(target, path[, type])
#
target
<字符串> | <缓冲区> | <网址>path
<字符串> | <缓冲区> | <网址>type
<字符串> 默认值:'file'
- 返回:<Promise>成功后,将执行
undefined
。
创建符号链接。
type
参数仅在 Windows 平台上使用,可以是'dir'
、
'file'
或'junction'
之一。Windows 连接点要求目标路径是绝对路径。当使用'junction'
时,target
参数将自动标准化为绝对路径。NTFS 卷上的连接点只能指向目录。
fsPromises.truncate(path[, len])
#
将path
处的内容截断(缩短或延长长度)为len
字节。
fsPromises.unlink(path)
#
如果path
引用符号链接,则删除该链接不会影响该链接引用的文件或目录。如果path
引用的文件路径不是符号链接,则该文件将被删除。
有关更多详细信息,请参阅 POSIX unlink(2)
文档。
fsPromises.utimes(path, atime, mtime)
#
path
<字符串> | <缓冲区> | <网址>atime
<数字> | <字符串> | <日期>mtime
<数字> | <字符串> | <日期>- 返回:<Promise>成功后,会执行
undefined
。
更改path
引用的对象的文件系统时间戳。
atime
和mtime
参数遵循以下规则:
- 值可以是表示 Unix 纪元时间的数字
Date
s,也可以是数字字符串,例如'123456789.0'
。 - 如果该值无法转换为数字,或者是
NaN
、Infinity
或-Infinity
,则会抛出Error
。
fsPromises.watch(filename[, options])
#
filename
<字符串> | <缓冲区> | <网址>options
<字符串> | <对象>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
<字符串> | <缓冲区> | <网址> | <FileHandle>文件名或FileHandle
data
<字符串> | <缓冲区> | <类型化数组> | <数据视图> | <异步迭代> | <可迭代> | <流>options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:'utf8'
mode
<整数> 默认值:0o666
flag
<string>查看文件系统的支持flags
。默认值:'w'
。signal
<AbortSignal>允许中止正在进行的 writeFile
- 返回:<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 });
// Abort the request before the promise settles.
controller.abort();
await promise;
} catch (err) {
// When a request is aborted - err is an AbortError
console.error(err);
}
中止正在进行的请求不会中止单个操作系统请求,而是中止内部缓冲fs.writeFile
的执行。
fsPromises.constants
#
返回一个包含文件系统操作常用常量的对象。该对象与fs.constants
相同。
有关详细信息,请参阅FS 常量。
回调接口#
回调 API 异步执行所有操作,不会阻塞事件循环,然后在完成或出错时调用回调函数。
回调 API 使用底层 Node.js 线程池在事件循环线程之外执行文件系统操作。这些操作不是同步的或线程安全的。对同一文件执行多个并发修改时必须小心,否则可能会发生数据损坏。
fs.access(path[, mode], callback)
#
测试用户对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';
// Check if the file exists in the current directory.
access(file, constants.F_OK, (err) => {
console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
});
// Check if the file is readable.
access(file, constants.R_OK, (err) => {
console.log(`${file} ${err ? 'is not readable' : 'is readable'}`);
});
// Check if the file is writable.
access(file, constants.W_OK, (err) => {
console.log(`${file} ${err ? 'is not writable' : 'is writable'}`);
});
// Check if the file is readable and 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
<字符串> | <缓冲区> | <网址> | <number>文件名或文件描述符data
<字符串> | <缓冲区>options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:'utf8'
mode
<整数> 默认值:0o666
flag
<string>查看文件系统的支持flags
。默认值:'a'
。
callback
<函数>err
<错误>
将数据异步附加到文件,如果文件尚不存在则创建该文件。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])
#
关闭文件描述符。除了可能的异常之外,不会向完成回调提供任何参数。
通过任何其他fs
操作对当前正在使用的任何文件描述符 ( fd
) 调用fs.close()
可能会导致未定义的行为。
有关更多详细信息,请参阅 POSIX close(2)
文档。
fs.copyFile(src, dest[, mode], callback)
#
src
<字符串> | <缓冲区> | <URL>要复制的源文件名dest
<字符串> | <缓冲区> | <URL>复制操作的目标文件名mode
<integer>用于复制操作的修饰符。默认值:0
。callback
<函数>
异步复制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 will be created or overwritten by default.
copyFile('source.txt', 'destination.txt', callback);
// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback);
fs.cp(src, dest[, options], callback)
#
src
<字符串> | <URL>要复制的源路径。dest
<字符串> | <URL>要复制到的目标路径。options
<对象>dereference
<boolean>取消引用符号链接。默认值:false
。errorOnExist
<boolean>当force
为false
且目标存在时,抛出错误。默认值:false
。filter
<Function>过滤复制文件/目录的函数。返回true
复制该项目,返回false
忽略它。还可以返回 解析为true
或false
的Promise
默认值:undefined
。src
<string>要复制的源路径。dest
<string>要复制到的目标路径。- 返回:<布尔值> | < Promise >
force
<boolean>覆盖现有文件或目录。如果您将其设置为 false 并且目标存在,则复制操作将忽略错误。使用errorOnExist
选项更改此行为。 默认值:true
。mode
<integer>用于复制操作的修饰符。默认值:0
。请参阅fs.copyFile()
的mode
标志。preserveTimestamps
<boolean>何时保留来自src
的true
时间戳。默认值:false
。recursive
<boolean>递归复制目录默认值:false
verbatimSymlinks
<boolean>当true
时,将跳过符号链接的路径解析。默认值:false
callback
<函数>
将整个目录结构从src
异步复制到dest
,包括子目录和文件。
将目录复制到另一个目录时,不支持 glob,行为类似于cp dir1/ dir2/
。
fs.createReadStream(path[, options])
#
与<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';
// Create a stream from some character device.
const stream = createReadStream('/dev/input/event0');
setTimeout(() => {
stream.close(); // This may not close the stream.
// Artificially marking end-of-stream, as if the underlying resource had
// indicated end-of-file by itself, allows the stream to close.
// This does not cancel pending read operations, and if there is such an
// operation, the process may still not be able to exit successfully
// until it finishes.
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>接受的任何一个。
如果'error'
或'finish'
上的 autoClose
设置为 true(默认行为),
文件描述符将自动关闭。如果autoClose
为 false,则即使出现错误,文件描述符也不会关闭。应用程序有责任关闭它并确保没有文件描述符泄漏。
默认情况下,流被销毁后将发出'close'
事件。将emitClose
选项设置为false
以更改此行为。
通过提供fs
选项,可以覆盖open
、write
、 writev
相应的 fs
实现和close
。
在不使用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)
#
通过检查文件系统来测试给定路径是否存在。然后使用 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)
#
设置文件的权限。除了可能的异常之外,不会向完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX fchmod(2)
文档。
fs.fchown(fd, uid, gid, callback)
#
设置文件的所有者。除了可能的异常之外,不会向完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX fchown(2)
文档。
fs.fdatasync(fd, callback)
#
强制所有当前排队的与文件关联的 I/O 操作进入操作系统的同步 I/O 完成状态。有关详细信息,请参阅 POSIX
fdatasync(2)
文档。除了可能的异常之外,不会向完成回调提供任何参数。
fs.fstat(fd[, options], callback)
#
fd
<整数>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。
callback
<函数>err
<错误>stats
<fs.Stats>
使用文件描述符的<fs.Stats>调用回调。
有关更多详细信息,请参阅 POSIX fstat(2)
文档。
fs.fsync(fd, callback)
#
请求将打开的文件描述符的所有数据刷新到存储设备。具体实现是操作系统和设备特定的。有关更多详细信息,请参阅 POSIX fsync(2)
文档。除了可能的异常之外,不会向完成回调提供任何参数。
fs.ftruncate(fd[, len], callback)
#
截断文件描述符。除了可能的异常之外,不会向完成回调提供任何参数。
有关更多详细信息,请参阅 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)
#
更改所提供的文件描述符引用的对象的文件系统时间戳。请参阅fs.utimes()
。
fs.lchmod(path, mode, callback)
#
更改符号链接的权限。除了可能的异常之外,不会向完成回调提供任何参数。
该方法仅在 macOS 上实现。
有关更多详细信息,请参阅 POSIX lchmod(2)
文档。
fs.lchown(path, uid, gid, callback)
#
设置符号链接的所有者。除了可能的异常之外,不会向完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX lchown(2)
文档。
fs.lutimes(path, atime, mtime, callback)
#
path
<字符串> | <缓冲区> | <网址>atime
<数字> | <字符串> | <日期>mtime
<数字> | <字符串> | <日期>callback
<函数>err
<错误>
以与fs.utimes()
相同的方式更改文件的访问和修改时间
,不同之处在于,如果路径引用符号链接,则不会取消引用该链接:而是符号链接的时间戳本身都改变了。
除了可能的异常之外,不会向完成回调提供任何参数。
fs.link(existingPath, newPath, callback)
#
创建从existingPath
到newPath
的新链接。有关更多详细信息,请参阅 POSIX
link(2)
文档。除了可能的异常之外,不会向完成回调提供任何参数。
fs.lstat(path[, options], callback)
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。
callback
<函数>err
<错误>stats
<fs.Stats>
检索路径引用的符号链接的<fs.Stats> 。该回调获取两个参数(err, stats)
,其中stats
是一个<fs.Stats>
对象。lstat()
与stat()
相同,但如果path
是符号链接,则链接本身会被统计,而不是它引用的文件。
有关更多详细信息,请参阅 POSIX lstat(2)
文档。
fs.mkdir(path[, options], callback)
#
path
<字符串> | <缓冲区> | <网址>options
<对象> | <整数>callback
<函数>err
<错误>path
<字符串> | <undefined>仅当创建的目录的recursive
设置为true
时才出现。
异步创建目录。
回调可能会出现异常,如果recursive
为true
,则创建的第一个目录路径为(err[, path])
。
如果未创建目录(例如,如果之前创建过目录),则当recursive
为true
时,path
仍可以为undefined
。
可选的options
参数可以是指定mode
(权限和粘性位)的整数,也可以是具有mode
属性和recursive
的对象
属性指示是否应创建父目录。仅当recursive
为
false 时,当path
是存在的目录时调用fs.mkdir()
才会导致错误。如果recursive
为 false 并且目录存在,则会发生EEXIST
错误。
import { mkdir } from 'node:fs';
// Create ./tmp/a/apple, regardless of whether ./tmp and ./tmp/a exist.
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
后面以创建唯一的临时目录。由于平台不一致,请避免在prefix
中尾随X
字符。某些平台(尤其是 BSD)可以返回六个以上的随机字符,并用随机字符替换prefix
中的尾随X
字符。
创建的目录路径作为字符串传递给回调的第二个参数。
可选的options
参数可以是指定编码的字符串,也可以是具有指定要使用的字符编码的encoding
属性的对象。
import { mkdtemp } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
mkdtemp(join(tmpdir(), 'foo-'), (err, directory) => {
if (err) throw err;
console.log(directory);
// Prints: /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';
// The parent directory for the new temporary directory
const tmpDir = tmpdir();
// This method is *INCORRECT*:
mkdtemp(tmpDir, (err, directory) => {
if (err) throw err;
console.log(directory);
// Will print something similar to `/tmpabc123`.
// A new temporary directory is created at the file system root
// rather than *within* the /tmp directory.
});
// This method is *CORRECT*:
import { sep } from 'node:path';
mkdtemp(`${tmpDir}${sep}`, (err, directory) => {
if (err) throw err;
console.log(directory);
// Will print something similar to `/tmp/abc123`.
// A new temporary directory is created within
// the /tmp directory.
});
fs.open(path[, flags[, mode]], callback)
#
path
<字符串> | <缓冲区> | <网址>flags
<字符串> | <number>查看文件系统flags
的支持。 默认值:'r'
。mode
<字符串> | <integer> 默认值:0o666
(可读可写)callback
<函数>
异步文件打开。有关更多详细信息,请参阅 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)
#
异步打开目录。有关更多详细信息,请参阅 POSIX opendir(3)
文档。
创建一个<fs.Dir>,其中包含用于读取和清理目录的所有其他函数。
encoding
选项在打开目录和后续读取操作时设置path
的编码。
fs.read(fd, buffer, offset, length, position, callback)
#
fd
<整数>buffer
<缓冲区> | <类型化数组> | <DataView>数据将写入的缓冲区。offset
<integer>buffer
中要写入数据的位置。length
<整数>要读取的字节数。position
<整数> | <bigint> | <null>指定从文件中的何处开始读取。如果position
为null
或-1
,将从当前文件位置读取数据,并更新文件位置。如果position
是整数,则文件位置将保持不变。callback
<函数>
从fd
指定的文件中读取数据。
回调函数提供三个参数(err, bytesRead, buffer)
。
如果文件没有同时修改,则当读取的字节数为零时到达文件结尾。
如果此方法作为其util.promisify()
ed 版本调用,它将返回具有bytesRead
和buffer
属性的 Object
的 Promise 。
fs.read(fd[, options], callback)
#
与fs.read()
函数类似,此版本采用可选的
options
对象。如果没有指定options
对象,它将默认使用上述值。
fs.read(fd, buffer[, options], callback)
#
与fs.read()
函数类似,此版本采用可选的
options
对象。如果没有指定options
对象,它将默认使用上述值。
fs.readdir(path[, options], callback)
#
path
<字符串> | <缓冲区> | <网址>options
<字符串> | <对象>callback
<函数>err
<错误>files
<字符串[]> | <缓冲区[]> | <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
<字符串> | <缓冲区> | <网址> | <integer>文件名或文件描述符options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:null
flag
<string>查看文件系统的支持flags
。默认值:'r'
。signal
<AbortSignal>允许中止正在进行的 readFile
callback
<函数>
异步读取文件的全部内容。
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, and 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) => {
// ...
});
// When you want to abort the request
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
引用的符号链接的内容。回调获取两个参数(err, linkString)
。
有关更多详细信息,请参阅 POSIX readlink(2)
文档。
可选的options
参数可以是指定编码的字符串,也可以是具有encoding
属性的对象,该属性指定用于传递给回调的链接路径的字符编码。如果encoding
设置为'buffer'
,则返回的链接路径将作为<Buffer>对象传递。
fs.readv(fd, buffers[, position], callback)
#
fd
<整数>buffers
<ArrayBufferView[]>position
<整数> | <null> 默认值:null
callback
<函数>err
<错误>bytesRead
<整数>buffers
<ArrayBufferView[]>
从fd
指定的文件中读取并使用readv()
写入 ArrayBufferView
数组。
position
是距应读取数据的文件开头的偏移量。如果为typeof position !== 'number'
,将从当前位置读取数据。
回调将提供三个参数:err
、bytesRead
和
buffers
。bytesRead
是从文件中读取的字节数。
如果此方法作为其util.promisify()
ed 版本调用,它将返回具有bytesRead
和buffers
属性的 Object
的 Promise 。
fs.realpath(path[, options], callback)
#
通过解析.
、..
和符号链接来异步计算规范路径名。
规范路径名不一定是唯一的。硬链接和绑定安装可以通过许多路径名公开文件系统实体。
此函数的行为类似于realpath(3)
,但有一些例外:
-
在不区分大小写的文件系统上不执行大小写转换。
-
符号链接的最大数量与平台无关,并且通常(远)高于本机
realpath(3)
实现支持的数量。
callback
有两个参数(err, resolvedPath)
。可以使用process.cwd
来解析相对路径。
仅支持可转换为 UTF8 字符串的路径。
可选的options
参数可以是指定编码的字符串,也可以是具有encoding
属性的对象,该属性指定用于传递给回调的路径的字符编码。如果encoding
设置为'buffer'
,则返回的路径将作为<Buffer>对象传递。
如果path
解析为套接字或管道,则该函数将返回该对象的系统相关名称。
fs.realpath.native(path[, options], callback)
#
异步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
处的文件异步重命名为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)
#
异步rmdir(2)
。除了可能的异常之外,不会向完成回调提供任何参数。
在文件(不是目录)上使用fs.rmdir()
会导致Windows 上的ENOENT
错误和 POSIX 上的ENOTDIR
错误。
要获得与rm -rf
Unix 命令类似的行为,请使用
带有选项{ recursive: true, force: true }
的fs.rm()
。
fs.rm(path[, options], callback)
#
path
<字符串> | <缓冲区> | <网址>options
<对象>force
<boolean>当true
时,如果path
不存在,则异常将被忽略。默认值:false
。maxRetries
<整数>如果是EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
遇到错误时,Node.js 将重试该操作,每次尝试都会延长retryDelay
毫秒的线性退避等待时间。该选项代表重试次数。如果recursive
选项不是true
,则忽略此选项。默认值:0
。recursive
<boolean>如果true
,则执行递归删除。在递归模式下,操作失败时会重试。默认值:false
。retryDelay
<整数>重试之间等待的时间(以毫秒为单位)。如果recursive
选项不是true
,则忽略此选项。 默认值:100
。
callback
<函数>err
<错误>
异步删除文件和目录(以标准 POSIX rm
实用程序为模型)。除了可能的异常之外,不会向完成回调提供任何参数。
fs.stat(path[, options], callback)
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。
callback
<函数>err
<错误>stats
<fs.Stats>
异步stat(2)
。该回调获取两个参数(err, stats)
,其中
stats
是一个<fs.Stats>对象。
如果出现错误,err.code
将是常见系统错误之一。
fs.stat()
遵循符号链接。使用fs.lstat()
查看链接本身。
不建议在调用 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.statfs(path[, options], callback)
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.StatFs>对象中的数值是否 应为bigint
。默认值:false
。
callback
<函数>err
<错误>stats
<fs.StatFs>
异步statfs(2)
。返回有关已安装文件系统的信息,其中包含path
。该回调获取两个参数(err, stats)
,其中stats
是一个<fs.StatFs>对象。
如果出现错误,err.code
将是常见系统错误之一。
fs.symlink(target, path[, type], callback)
#
target
<字符串> | <缓冲区> | <网址>path
<字符串> | <缓冲区> | <网址>type
<字符串> | <null> 默认值:null
callback
<函数>err
<错误>
创建名为path
的链接,指向target
。除了可能的异常之外,不会向完成回调提供任何参数。
有关更多详细信息,请参阅 POSIX symlink(2)
文档。
type
参数仅在 Windows 上可用,在其他平台上被忽略。它可以设置为'dir'
、'file'
或'junction'
。如果type
参数不是字符串,Node.js 将自动检测target
类型并使用'file'
或'dir'
。如果target
不存在,则将使用'file'
。Windows 连接点要求目标路径是绝对路径。当使用'junction'
时,
target
参数将自动标准化为绝对路径。NTFS 卷上的连接点只能指向目录。
相对目标是相对于链接的父目录的。
import { symlink } from 'node:fs';
symlink('./mew', './mewtwo', callback);
上面的示例创建了一个符号链接mewtwo
,它指向同一目录中的mew
:
$ tree .
.
├── mew
└── mewtwo -> ./mew
fs.truncate(path[, len], callback)
#
截断文件。除了可能的异常之外,不会向完成回调提供任何参数。文件描述符也可以作为第一个参数传递。在本例中,将调用fs.ftruncate()
。
import { truncate } from 'node:fs';
// Assuming that 'path/file.txt' is a regular file.
truncate('path/file.txt', (err) => {
if (err) throw err;
console.log('path/file.txt was truncated');
});
const { truncate } = require('node:fs');
// Assuming that 'path/file.txt' is a regular file.
truncate('path/file.txt', (err) => {
if (err) throw err;
console.log('path/file.txt was truncated');
});
不推荐使用传递文件描述符,并且可能会导致将来抛出错误。
有关更多详细信息,请参阅 POSIX truncate(2)
文档。
fs.unlink(path, callback)
#
异步删除文件或符号链接。除了可能的异常之外,不会向完成回调提供任何参数。
import { unlink } from 'node:fs';
// Assuming that 'path/file.txt' is a regular file.
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
<字符串> | <缓冲区> | <网址>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
<字符串> | <缓冲区> | <网址>atime
<数字> | <字符串> | <日期>mtime
<数字> | <字符串> | <日期>callback
<函数>err
<错误>
更改path
引用的对象的文件系统时间戳。
atime
和mtime
参数遵循以下规则:
- 值可以是表示 Unix 纪元时间(以秒为单位)的数字、
Date
s,也可以是类似'123456789.0'
的数字字符串。 - 如果该值无法转换为数字,或者是
NaN
、Infinity
或-Infinity
,则会抛出Error
。
fs.watch(filename[, options][, listener])
#
filename
<字符串> | <缓冲区> | <网址>options
<字符串> | <对象>persistent
<boolean>指示只要正在监视文件,进程是否应继续运行。默认值:true
。recursive
<boolean>指示是否应监视所有子目录,或仅监视当前目录。这在指定目录时适用,并且仅在支持的平台上适用(请参阅注意事项)。默认值:false
。encoding
<string>指定用于传递给侦听器的文件名的字符编码。默认值:'utf8'
。signal
<AbortSignal>允许使用 AbortSignal 关闭观察者。
listener
<函数> | <未定义> 默认值: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()
,它使用统计轮询,但这种方法速度较慢且不太可靠。
索引节点#
在 Linux 和 macOS 系统上,fs.watch()
解析inode的路径并监视 inode。如果监视的路径被删除并重新创建,则会为其分配一个新的 inode。监视将发出删除事件,但将继续监视原始索引节点。新索引节点的事件将不会被发出。这是预期的行为。
AIX 文件在文件的生命周期内保留相同的 inode。在 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
<字符串> | <缓冲区> | <网址>options
<对象>listener
<函数>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}`);
});
这些 stat 对象是fs.Stat
的实例。如果bigint
选项为true
,则这些对象中的数值将指定为BigInt
。
要在文件修改时收到通知,而不仅仅是访问文件时,有必要比较curr.mtimeMs
和prev.mtimeMs
。
当fs.watchFile
操作导致ENOENT
错误时,它将调用侦听器一次,并将所有字段清零(或者,对于日期,将 Unix 纪元)。如果稍后创建该文件,将使用最新的统计对象再次调用侦听器。这是自 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
<整数>buffer
<缓冲区> | <类型化数组> | <数据视图>offset
<整数> 默认值:0
length
<整数> 默认值:buffer.byteLength - offset
position
<整数> | <null> 默认值:null
callback
<函数>
将buffer
写入fd
指定的文件。
offset
确定要写入的缓冲区部分,而length
是一个整数,指定要写入的字节数。
position
指的是距应写入此数据的文件开头的偏移量。如果是typeof position !== 'number'
,数据将写入当前位置。请参阅pwrite(2)
。
回调将获得三个参数(err, bytesWritten, buffer)
,其中
bytesWritten
指定从buffer
写入了多少字节。
如果此方法作为其util.promisify()
ed 版本调用,它将返回具有bytesWritten
和buffer
属性的 Object
的 Promise 。
在同一个文件上多次使用fs.write()
而不等待回调是不安全的。对于这种情况,建议使用fs.createWriteStream()
。
在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核忽略位置参数并始终将数据附加到文件末尾。
fs.write(fd, buffer[, options], callback)
#
将buffer
写入fd
指定的文件。
与上面的fs.write
函数类似,此版本采用可选的options
对象。如果没有指定options
对象,它将默认使用上述值。
fs.write(fd, string[, position[, encoding]], callback)
#
fd
<整数>string
<字符串> | <对象>position
<整数> | <null> 默认值:null
encoding
<字符串> 默认值:'utf8'
callback
<函数>
将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
<字符串> | <缓冲区> | <网址> | <integer>文件名或文件描述符data
<字符串> | <缓冲区> | <类型化数组> | <数据视图> | <对象>options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:'utf8'
mode
<整数> 默认值:0o666
flag
<string>查看文件系统的支持flags
。默认值:'w'
。signal
<AbortSignal>允许中止正在进行的 writeFile
callback
<函数>
当file
是文件名时,异步将数据写入文件,如果文件已存在则替换该文件。data
可以是字符串或缓冲区。
当file
是文件描述符时,行为类似于直接调用
fs.write()
(推荐)。请参阅下面有关使用文件描述符的注释。
如果data
是缓冲区,则忽略 encoding
选项。
mode
选项仅影响新创建的文件。请参阅fs.open()
了解更多详情。
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) => {
// When a request is aborted - the callback is called with an AbortError
});
// When the request should be aborted
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
<整数>buffers
<ArrayBufferView[]>position
<整数> | <null> 默认值:null
callback
<函数>err
<错误>bytesWritten
<整数>buffers
<ArrayBufferView[]>
使用
writev()
将 ArrayBufferView
数组写入fd
指定的文件。
position
是距应写入此数据的文件开头的偏移量。如果为typeof position !== 'number'
,则数据将写入当前位置。
回调将提供三个参数:err
、bytesWritten
和
buffers
。bytesWritten
是从buffers
写入的字节数。
如果此方法是util.promisify()
ed,它将返回具有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
<字符串> | <缓冲区> | <网址> | <number>文件名或文件描述符data
<字符串> | <缓冲区>options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:'utf8'
mode
<整数> 默认值: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) {
/* Handle the error */
}
如果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) {
/* Handle the error */
} 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
<整数>
关闭文件描述符。返回undefined
。
通过任何其他fs
操作对当前正在使用的任何文件描述符 ( fd
) 调用fs.closeSync()
可能会导致未定义的行为。
有关更多详细信息,请参阅 POSIX close(2)
文档。
fs.copyFileSync(src, dest[, mode])
#
src
<字符串> | <缓冲区> | <URL>要复制的源文件名dest
<字符串> | <缓冲区> | <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 will be created or overwritten by default.
copyFileSync('source.txt', 'destination.txt');
console.log('source.txt was copied to destination.txt');
// By using COPYFILE_EXCL, the operation will fail if destination.txt exists.
copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL);
fs.cpSync(src, dest[, options])
#
src
<字符串> | <URL>要复制的源路径。dest
<字符串> | <URL>要复制到的目标路径。options
<对象>dereference
<boolean>取消引用符号链接。默认值:false
。errorOnExist
<boolean>当force
为false
且目标存在时,抛出错误。默认值:false
。filter
<Function>过滤复制文件/目录的函数。返回true
复制该项目,返回false
忽略它。默认值:undefined
force
<boolean>覆盖现有文件或目录。如果您将其设置为 false 并且目标存在,则复制操作将忽略错误。使用errorOnExist
选项来更改此行为。 默认值:true
。mode
<integer>用于复制操作的修饰符。默认值:0
。请参阅fs.copyFileSync()
的mode
标志。preserveTimestamps
<boolean>何时保留来自src
的true
时间戳。默认值:false
。recursive
<boolean>递归复制目录默认值:false
verbatimSymlinks
<boolean>当true
时,将跳过符号链接的路径解析。默认值:false
将整个目录结构从src
同步复制到dest
,包括子目录和文件。
将目录复制到另一个目录时,不支持 glob,行为类似于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
<整数>
强制所有当前排队的与文件关联的 I/O 操作进入操作系统的同步 I/O 完成状态。有关详细信息,请参阅 POSIX
fdatasync(2)
文档。返回undefined
。
fs.fstatSync(fd[, options])
#
fd
<整数>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。
- 返回:<fs.Stats>
检索文件描述符的<fs.Stats> 。
有关更多详细信息,请参阅 POSIX fstat(2)
文档。
fs.fsyncSync(fd)
#
fd
<整数>
请求将打开的文件描述符的所有数据刷新到存储设备。具体实现是操作系统和设备特定的。有关更多详细信息,请参阅 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
引用的符号链接的文件系统时间戳。返回undefined
,或者参数错误或操作失败时抛出异常。这是fs.lutimes()
的同步版本。
fs.linkSync(existingPath, newPath)
#
创建从existingPath
到newPath
的新链接。有关更多详细信息,请参阅 POSIX
link(2)
文档。返回undefined
。
fs.lstatSync(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>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
<字符串> | <缓冲区> | <网址>flags
<字符串> | <数字> 默认值:'r'
。请参阅文件系统flags
的支持。mode
<字符串> | <整数> 默认值:0o666
- 返回:<数字>
返回表示文件描述符的整数。
有关详细信息,请参阅此 API 异步版本的文档:fs.open()
。
fs.readdirSync(path[, options])
#
读取目录的内容。
有关更多详细信息,请参阅 POSIX readdir(3)
文档。
可选的options
参数可以是指定编码的字符串,也可以是具有encoding
属性的对象,指定用于返回的文件名的字符编码。如果encoding
设置为'buffer'
,则返回的文件名将作为<Buffer>对象传递。
如果options.withFileTypes
设置为true
,结果将包含
<fs.Dirent>对象。
fs.readFileSync(path[, options])
#
path
<字符串> | <缓冲区> | <网址> | <integer>文件名或文件描述符options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:null
flag
<string>查看文件系统的支持flags
。默认值:'r'
。
- 返回:<字符串> | <缓冲区>
返回path
的内容。
有关详细信息,请参阅此 API 异步版本的文档:fs.readFile()
。
如果指定了encoding
选项,则此函数返回一个字符串。否则它返回一个缓冲区。
与fs.readFile()
类似,当路径是目录时,
fs.readFileSync()
的行为是特定于平台的。
import { readFileSync } from 'node:fs';
// macOS, Linux, and Windows
readFileSync('<directory>');
// => [Error: EISDIR: illegal operation on a directory, read <directory>]
// FreeBSD
readFileSync('<directory>'); // => <data>
fs.readlinkSync(path[, options])
#
返回符号链接的字符串值。
有关更多详细信息,请参阅 POSIX readlink(2)
文档。
可选的options
参数可以是指定编码的字符串,也可以是具有encoding
属性的对象,指定用于返回的链接路径的字符编码。如果encoding
设置为'buffer'
,则返回的链接路径将作为<Buffer>对象传递。
fs.readSync(fd, buffer, offset, length[, position])
#
fd
<整数>buffer
<缓冲区> | <类型化数组> | <数据视图>offset
<整数>length
<整数>position
<整数> | <bigint> | <null> 默认值:null
- 返回:<数字>
返回bytesRead
的数量。
有关详细信息,请参阅此 API 异步版本的文档:fs.read()
。
fs.readSync(fd, buffer[, options])
#
返回bytesRead
的数量。
与上面的fs.readSync
函数类似,此版本采用可选的options
对象。如果没有指定options
对象,它将默认使用上述值。
有关详细信息,请参阅此 API 异步版本的文档:fs.read()
。
fs.readvSync(fd, buffers[, position])
#
fd
<整数>buffers
<ArrayBufferView[]>position
<整数> | <null> 默认值:null
- 返回:<number>读取的字节数。
有关详细信息,请参阅此 API 异步版本的文档:fs.readv()
。
fs.realpathSync(path[, options])
#
返回解析的路径名。
有关详细信息,请参阅此 API 异步版本的文档:fs.realpath()
。
fs.realpathSync.native(path[, options])
#
同步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])
#
同步rmdir(2)
。返回undefined
。
在文件(而非目录)上使用fs.rmdirSync()
会导致Windows 上的ENOENT
错误和 POSIX 上的ENOTDIR
错误。
要获得与rm -rf
Unix 命令类似的行为,请使用
带有选项{ recursive: true, force: true }
的fs.rmSync()
。
fs.rmSync(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>force
<boolean>当true
时,如果path
不存在,则异常将被忽略。默认值:false
。maxRetries
<整数>如果是EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
遇到错误时,Node.js 将重试该操作,每次尝试都会延长retryDelay
毫秒的线性退避等待时间。该选项代表重试次数。如果recursive
选项不是true
,则忽略此选项。默认值:0
。recursive
<boolean>如果为true
,则执行递归目录删除。在递归模式下,操作失败时会重试。默认值:false
。retryDelay
<整数>重试之间等待的时间(以毫秒为单位)。如果recursive
选项不是true
,则忽略此选项。 默认值:100
。
同步删除文件和目录(以标准 POSIX rm
实用程序为模型)。返回undefined
。
fs.statSync(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.Stats>对象中的数值是否 应为bigint
。默认值:false
。throwIfNoEntry
<boolean>如果不存在文件系统条目,是否抛出异常,而不是返回undefined
。 默认值:true
。
- 返回:<fs.Stats>
检索路径的<fs.Stats> 。
fs.statfsSync(path[, options])
#
path
<字符串> | <缓冲区> | <网址>options
<对象>bigint
<boolean>返回的<fs.StatFs>对象中的数值是否 应为bigint
。默认值:false
。
- 返回:<fs.StatFs>
同步statfs(2)
。返回有关已安装文件系统的信息,其中包含path
。
如果出现错误,err.code
将是常见系统错误之一。
fs.symlinkSync(target, path[, type])
#
返回undefined
。
有关详细信息,请参阅此 API 异步版本的文档:fs.symlink()
。
fs.truncateSync(path[, len])
#
截断文件。返回undefined
。文件描述符也可以作为第一个参数传递。在本例中,将调用fs.ftruncateSync()
。
不推荐使用传递文件描述符,并且可能会导致将来抛出错误。
fs.unlinkSync(path)
#
同步unlink(2)
。返回undefined
。
fs.utimesSync(path, atime, mtime)
#
返回undefined
。
有关详细信息,请参阅此 API 异步版本的文档:fs.utimes()
。
fs.writeFileSync(file, data[, options])
#
file
<字符串> | <缓冲区> | <网址> | <integer>文件名或文件描述符data
<字符串> | <缓冲区> | <类型化数组> | <数据视图> | <对象>options
<对象> | <字符串>encoding
<字符串> | <null> 默认值:'utf8'
mode
<整数> 默认值:0o666
flag
<string>查看文件系统的支持flags
。默认值:'w'
。
返回undefined
。
mode
选项仅影响新创建的文件。请参阅fs.open()
了解更多详情。
有关详细信息,请参阅此 API 异步版本的文档:fs.writeFile()
。
fs.writeSync(fd, buffer, offset[, length[, position]])
#
fd
<整数>buffer
<缓冲区> | <类型化数组> | <数据视图>offset
<整数> 默认值:0
length
<整数> 默认值:buffer.byteLength - offset
position
<整数> | <null> 默认值:null
- 返回:<number>写入的字节数。
有关详细信息,请参阅此 API 异步版本的文档:fs.write(fd, buffer...)
。
fs.writeSync(fd, buffer[, options])
#
有关详细信息,请参阅此 API 异步版本的文档:fs.write(fd, buffer...)
。
fs.writeSync(fd, string[, position[, encoding]])
#
有关详细信息,请参阅此 API 异步版本的文档:fs.write(fd, string...)
。
fs.writevSync(fd, buffers[, position])
#
fd
<整数>buffers
<ArrayBufferView[]>position
<整数> | <null> 默认值:null
- 返回:<number>写入的字节数。
有关详细信息,请参阅此 API 异步版本的文档:fs.writev()
。
常见对象#
公共对象由所有文件系统 API 变体(promise、callback 和 synchronous)共享。
类: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 ,该 Promise 将在资源关闭后得到解决。
dir.close(callback)
#
异步关闭目录的底层资源句柄。后续读取将导致错误。
资源句柄关闭后将调用callback
。
dir.closeSync()
#
同步关闭目录的底层资源句柄。后续读取将导致错误。
dir.path
#
提供给fs.opendir()
、
fs.opendirSync()
或fsPromises.opendir()
的该目录的只读路径。
dir.read()
#
- 返回:<Promise>包含<fs.Dirent> | <空>
通过readdir(3)
作为
<fs.Dirent>异步读取下一个目录条目。
返回一个 Promise ,该 Promise 将通过<fs.Dirent>或null
解析
(如果没有更多目录条目可供读取)。
此函数返回的目录条目不按照操作系统的底层目录机制提供的特定顺序排列。迭代目录时添加或删除的条目可能不会包含在迭代结果中。
dir.read(callback)
#
callback
<函数>err
<错误>dirent
<fs.Dirent> | <空>
通过readdir(3)
作为
<fs.Dirent>异步读取下一个目录条目。
读取完成后,将使用<fs.Dirent>调用
callback
,如果没有更多目录条目可供读取,则调用 null
。
此函数返回的目录条目不按照操作系统的底层目录机制提供的特定顺序排列。迭代目录时添加或删除的条目可能不会包含在迭代结果中。
dir.readSync()
#
- 返回:<fs.Dirent> | <空>
同步读取下一个目录条目作为<fs.Dirent>。有关更多详细信息,请参阅 POSIX readdir(3)
文档。
如果没有更多的目录条目可供读取,则将返回null
。
此函数返回的目录条目不按照操作系统的底层目录机制提供的特定顺序排列。迭代目录时添加或删除的条目可能不会包含在迭代结果中。
dir[Symbol.asyncIterator]()
#
异步迭代目录,直到读取所有条目。有关更多详细信息,请参阅 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()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述块设备,则返回true
。
dirent.isCharacterDevice()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述字符设备,则返回true
。
dirent.isDirectory()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述文件系统目录,则返回true
。
dirent.isFIFO()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述先进先出 (FIFO) 管道,则返回true
。
dirent.isFile()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述常规文件,则返回true
。
dirent.isSocket()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述套接字,则返回true
。
dirent.isSymbolicLink()
#
- 返回:<布尔值>
如果<fs.Dirent>对象描述符号链接,则返回true
。
dirent.name
#
此<fs.Dirent>对象引用的文件名。该值的类型由传递给 fs.readdir()
或
fs.readdirSync()
的 options.encoding
确定。
dirent.path
#
此<fs.Dirent>对象引用的基本路径。
类:fs.FSWatcher
#
成功调用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';
// Example when handled through fs.watch() listener
watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
if (filename) {
console.log(filename);
// Prints: <Buffer ...>
}
});
事件:'close'
#
当观察者停止观察变化时发出。关闭的 <fs.FSWatcher>对象在事件处理程序中不再可用。
事件:'error'
#
error
<错误>
当观看文件时发生错误时发出。出错的 <fs.FSWatcher>对象在事件处理程序中不再可用。
watcher.close()
#
停止监视给定<fs.FSWatcher>上的更改。一旦停止, <fs.FSWatcher>对象将不再可用。
watcher.ref()
#
调用时,请求只要
<fs.FSWatcher>处于事件状态,Node.js 事件循环就不会退出。多次调用watcher.ref()
不会有任何效果。
默认情况下,所有<fs.FSWatcher>对象都会被“ref'ed”,因此通常不需要调用watcher.ref()
,除非之前已调用过watcher.unref()
。
watcher.unref()
#
调用时,事件的<fs.FSWatcher>对象将不需要 Node.js 事件循环保持事件状态。如果没有其他事件保持事件循环运行,则进程可能会在调用<fs.FSWatcher>对象的回调之前退出。多次调用watcher.unref()
不会有任何效果。
类:fs.StatWatcher
#
成功调用fs.watchFile()
方法将返回一个新的<fs.StatWatcher>
对象。
watcher.ref()
#
调用时,请求只要
<fs.StatWatcher>处于事件状态,Node.js 事件循环就不会退出。多次调用watcher.ref()
不会有任何效果。
默认情况下,所有<fs.StatWatcher>对象都会被“ref'ed”,因此通常不需要调用watcher.ref()
,除非之前已调用过watcher.unref()
。
watcher.unref()
#
调用时,事件的<fs.StatWatcher>对象将不需要 Node.js 事件循环保持事件状态。如果没有其他事件保持事件循环运行,则该进程可能会在调用<fs.StatWatcher>对象的回调之前退出。多次调用watcher.unref()
不会有任何效果。
类:fs.ReadStream
#
<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()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述块设备,则返回true
。
stats.isCharacterDevice()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述字符设备,则返回true
。
stats.isDirectory()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述文件系统目录,则返回true
。
如果<fs.Stats>对象是从fs.lstat()
获取的,则此方法将始终返回false
。这是因为fs.lstat()
返回有关符号链接本身的信息,而不是它解析到的路径。
stats.isFIFO()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述先进先出 (FIFO) 管道,则返回true
。
stats.isFile()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述常规文件,则返回true
。
stats.isSocket()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述套接字,则返回true
。
stats.isSymbolicLink()
#
- 返回:<布尔值>
如果<fs.Stats>对象描述符号链接,则返回true
。
stats.dev
#
包含该文件的设备的数字标识符。
stats.ino
#
文件系统特定的“Inode”号。
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
被传递到生成对象的方法中时,属性将为bigints,否则它们将为numeric。
atimeNs
、mtimeNs
、ctimeNs
、birthtimeNs
属性是
保存相应时间(以纳秒为单位)的bigint 。仅当将bigint: true
传递到生成对象的方法时,它们才会出现。它们的精度是特定于平台的。
atime
、mtime
、ctime
和birthtime
是
不同时间的Date
对象替代表示。Date
和数值
未连接。分配新的数值或改变Date
值不会反映在相应的替代表示中。
stat 对象中的时间具有以下语义:
atime
“访问时间”:上次访问文件数据的时间。由mknod(2)
、utimes(2)
和read(2)
系统调用更改。mtime
“修改时间”:文件数据最后修改的时间。由mknod(2)
、utimes(2)
和write(2)
系统调用更改。ctime
“更改时间”:文件状态最后一次更改(inode 数据修改)的时间。由chmod(2)
、chown(2)
、link(2)
、mknod(2)
、rename(2)
、unlink(2)
更改、utimes(2)
、read(2)
和write(2)
系统调用。birthtime
“出生时间”:文件创建时间。创建文件时设置一次。在出生时间不可用的文件系统上,此字段可能会保存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.StatFs
#
提供有关已安装文件系统的信息。
从fs.statfs()
返回的对象及其同步对象都属于这种类型。如果传递给这些方法的options
中的bigint
是 true
,则数值将为bigint
而不是number
。
StatFs {
type: 1397114950,
bsize: 4096,
blocks: 121938943,
bfree: 61058895,
bavail: 61058895,
files: 999,
ffree: 1000000
}
bigint
版本:
StatFs {
type: 1397114950n,
bsize: 4096n,
blocks: 121938943n,
bfree: 61058895n,
bavail: 61058895n,
files: 999n,
ffree: 1000000n
}
statfs.bavail
#
非特权用户可以使用免费块。
statfs.bfree
#
文件系统中的空闲块。
statfs.blocks
#
文件系统中的总数据块。
statfs.bsize
#
最佳传输块大小。
statfs.ffree
#
文件系统中的空闲文件节点。
statfs.files
#
文件系统中的文件节点总数。
statfs.type
#
文件系统的类型。
类: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])
#
关闭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 特定定义在 Windows 上不可用。对于便携式应用,建议在使用前检查它们是否存在。
要使用多个常量,请使用按位 OR |
运算符。
例子:
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()
操作
之前完成:
const fs = require('node:fs');
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`stats: ${JSON.stringify(stats)}`);
});
在调用另一个操作之前等待一个操作的结果来正确排序操作非常重要:
import { rename, stat } from 'node:fs/promises';
const oldPath = '/tmp/hello';
const newPath = '/tmp/world';
try {
await rename(oldPath, newPath);
const stats = await stat(newPath);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
const { rename, stat } = require('node:fs/promises');
(async function(oldPath, newPath) {
try {
await rename(oldPath, newPath);
const stats = await stat(newPath);
console.log(`stats: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('there was an error:', error.message);
}
})('/tmp/hello', '/tmp/world');
或者,在使用回调 API 时,将fs.stat()
调用移至fs.rename()
操作的回调中:
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
操作接受可以使用file:
协议以字符串、 <Buffer>或<URL>对象形式指定的文件路径。
字符串路径#
字符串路径被解释为标识绝对或相对文件名的 UTF-8 字符序列。相对路径将相对于通过调用process.cwd()
确定的当前工作目录进行解析。
在 POSIX 上使用绝对路径的示例:
import { open } from 'node:fs/promises';
let fd;
try {
fd = await open('/open/some/file.txt', 'r');
// Do something with the file
} finally {
await fd?.close();
}
在 POSIX 上使用相对路径的示例(相对于process.cwd()
):
import { open } from 'node:fs/promises';
let fd;
try {
fd = await open('file.txt', 'r');
// Do something with the file
} finally {
await fd?.close();
}
文件 URL 路径#
对于大多数node:fs
模块函数,可以使用file:
协议将path
或filename
参数作为<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';
// On Windows :
// - WHATWG file URLs with hostname convert to UNC path
// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
readFileSync(new URL('file://hostname/p/a/t/h/file'));
// - WHATWG file URLs with drive letters convert to absolute path
// file:///C:/tmp/hello => C:\tmp\hello
readFileSync(new URL('file:///C:/tmp/hello'));
// - WHATWG file URLs without hostname must have a drive letters
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';
// On other platforms:
// - WHATWG file URLs with hostname are unsupported
// 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 file URLs convert to absolute path
// file:///tmp/hello => /tmp/hello
readFileSync(new URL('file:///tmp/hello'));
包含编码斜杠字符的file:
<URL>将在所有平台上导致错误:
import { readFileSync } from 'node:fs';
// On 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 */
// On 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';
// On 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>指定的路径主要在某些将文件路径视为不透明字节序列的 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');
// Do something with the file
} 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;
}
// use stat
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();
// use stat
} finally {
await file.close();
}
线程池使用#
所有回调和基于 Promise 的文件系统 API( fs.FSWatcher()
除外
)都使用 libuv 的线程池。这可能会对某些应用程序产生令人惊讶的负面性能影响。有关更多信息,请参阅
UV_THREADPOOL_SIZE
文档。
文件系统标志#
只要flag
选项采用字符串,以下标志就可用。
-
'a'
:打开文件进行追加。如果文件不存在,则创建该文件。 -
'ax'
:与'a'
类似,但如果路径存在则失败。 -
'a+'
:打开文件进行读取和追加。如果文件不存在,则创建该文件。 -
'ax+'
:与'a+'
类似,但如果路径存在则失败。 -
'as'
:打开文件以同步模式追加。如果文件不存在,则创建该文件。 -
'as+'
:打开文件以同步模式读取和追加。如果文件不存在,则创建该文件。 -
'r'
:打开文件进行读取。如果文件不存在,则会发生异常。 -
'rs'
:以同步模式打开文件进行读取。如果文件不存在,则会发生异常。 -
'r+'
:打开文件进行读写。如果文件不存在,则会发生异常。 -
'rs+'
:打开文件以同步模式读写。指示操作系统绕过本地文件系统缓存。这主要用于打开 NFS 挂载上的文件,因为它允许跳过可能过时的本地缓存。它对 I/O 性能有非常实际的影响,因此除非需要,否则不建议使用此标志。
这不会将
fs.open()
或fsPromises.open()
转变为同步阻塞调用。如果需要同步操作, 则应使用类似fs.openSync()
的内容。 -
'w'
:打开文件进行写入。文件被创建(如果不存在)或截断(如果存在)。 -
'wx'
:与'w'
类似,但如果路径存在则失败。 -
'w+'
:打开文件进行读写。文件被创建(如果不存在)或截断(如果存在)。 -
'wx+'
:与'w+'
类似,但如果路径存在则失败。
flag
也可以是open(2)
记录的数字;常用常量可从fs.constants
获取。在 Windows 上,标志会在适用的情况下转换为等效的标志,例如O_WRONLY
转换为FILE_GENERIC_WRITE
,或O_EXCL|O_CREAT
转换为CREATE_NEW
,如所接受的CreateFileW
。
如果路径已存在,独占标志'x'
(open(2)
中的O_EXCL
标志)会导致操作返回错误。在 POSIX 上,如果路径是符号链接,则即使链接指向不存在的路径,使用O_EXCL
也会返回错误。独占标志可能不适用于网络文件系统。
在 Linux 上,当文件以追加模式打开时,位置写入不起作用。内核忽略位置参数并始终将数据附加到文件末尾。
修改文件而不是替换它可能需要将flag
选项设置为'r+'
而不是默认的'w'
。
某些标志的行为是特定于平台的。因此,在 macOS 和 Linux 上使用'a+'
标志打开目录(如下例所示)将返回错误。
相反,在 Windows 和 FreeBSD 上,将返回文件描述符或FileHandle
。
// macOS and Linux
fs.open('<directory>', 'a+', (err, fd) => {
// => [Error: EISDIR: illegal operation on a directory, open <directory>]
});
// Windows and FreeBSD
fs.open('<directory>', 'a+', (err, fd) => {
// => null, <fd>
});
在 Windows 上,使用'w'
标志(通过fs.open()
、fs.writeFile()
或fsPromises.open()
)打开现有隐藏文件将失败,并显示
EPERM
。可以使用'r+'
标志打开现有的隐藏文件进行写入。
调用fs.ftruncate()
或filehandle.truncate()
可用于重置文件内容。