- assert - 断言
- async_hooks - 异步钩子
- Buffer - 缓冲器
- child_process - 子进程
- cluster - 集群
- console - 控制台
- crypto - 加密
- debugger - 调试器
- dgram - 数据报
- dns - 域名服务器
- domain - 域
- Error - 错误
- events - 事件触发器
- fs - 文件系统
- global - 全局变量
- http - HTTP
- http2 - HTTP/2
- https - HTTPS
- inspector - 检查器
- module - 模块
- net - 网络
- os - 操作系统
- path - 路径
- perf_hooks - 性能钩子
- process - 进程
- punycode - 域名代码
- querystring - 查询字符串
- readline - 逐行读取
- repl - 交互式解释器
- stream - 流
- string_decoder - 字符串解码器
- timer - 定时器
- tls - 安全传输层
- trace_events - 跟踪事件
- tty - 终端
- url - URL
- util - 实用工具
- v8 - V8引擎
- vm - 虚拟机
- wasi - WASI
- worker_threads - 工作线程
- zlib - 压缩
目录
- fs(文件系统)
- 同步的示例
- 回调的示例
- Promise 的示例
- 回调与基于 promise 的操作的顺序
- 文件路径
- 文件描述符
- 线程池的使用
- fs.Dir 类
- fs.Dirent 类
- fs.FSWatcher 类
- fs.StatWatcher 类
- fs.ReadStream 类
- fs.Stats 类
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isDirectory()
stats.isFIFO()
stats.isFile()
stats.isSocket()
stats.isSymbolicLink()
stats.dev
stats.ino
stats.mode
stats.nlink
stats.uid
stats.gid
stats.rdev
stats.size
stats.blksize
stats.blocks
stats.atimeMs
stats.mtimeMs
stats.ctimeMs
stats.birthtimeMs
stats.atimeNs
stats.mtimeNs
stats.ctimeNs
stats.birthtimeNs
stats.atime
stats.mtime
stats.ctime
stats.birthtime
- 文件属性的时间值
- fs.WriteStream 类
fs.access(path[, mode], callback)
fs.accessSync(path[, mode])
fs.appendFile(path, data[, options], callback)
fs.appendFileSync(path, data[, options])
fs.chmod(path, mode, callback)
fs.chmodSync(path, mode)
fs.chown(path, uid, gid, callback)
fs.chownSync(path, uid, gid)
fs.close(fd, callback)
fs.closeSync(fd)
fs.constants
fs.copyFile(src, dest[, mode], callback)
fs.copyFileSync(src, dest[, mode])
fs.createReadStream(path[, options])
fs.createWriteStream(path[, options])
fs.exists(path, callback)
fs.existsSync(path)
fs.fchmod(fd, mode, callback)
fs.fchmodSync(fd, mode)
fs.fchown(fd, uid, gid, callback)
fs.fchownSync(fd, uid, gid)
fs.fdatasync(fd, callback)
fs.fdatasyncSync(fd)
fs.fstat(fd[, options], callback)
fs.fstatSync(fd[, options])
fs.fsync(fd, callback)
fs.fsyncSync(fd)
fs.ftruncate(fd[, len], callback)
fs.ftruncateSync(fd[, len])
fs.futimes(fd, atime, mtime, callback)
fs.futimesSync(fd, atime, mtime)
fs.lchmod(path, mode, callback)
fs.lchmodSync(path, mode)
fs.lchown(path, uid, gid, callback)
fs.lchownSync(path, uid, gid)
fs.lutimes(path, atime, mtime, callback)
fs.lutimesSync(path, atime, mtime)
fs.link(existingPath, newPath, callback)
fs.linkSync(existingPath, newPath)
fs.lstat(path[, options], callback)
fs.lstatSync(path[, options])
fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])
fs.mkdtemp(prefix[, options], callback)
fs.mkdtempSync(prefix[, options])
fs.open(path[, flags[, mode]], callback)
fs.opendir(path[, options], callback)
fs.opendirSync(path[, options])
fs.openSync(path[, flags, mode])
fs.read(fd, buffer, offset, length, position, callback)
fs.read(fd, [options,] callback)
fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
fs.readFile(path[, options], callback)
fs.readFileSync(path[, options])
fs.readlink(path[, options], callback)
fs.readlinkSync(path[, options])
fs.readSync(fd, buffer, offset, length, position)
fs.readSync(fd, buffer, [options])
fs.readv(fd, buffers[, position], callback)
fs.readvSync(fd, buffers[, position])
fs.realpath(path[, options], callback)
fs.realpath.native(path[, options], callback)
fs.realpathSync(path[, options])
fs.realpathSync.native(path[, options])
fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
fs.rmdir(path[, options], callback)
fs.rmdirSync(path[, options])
fs.rm(path[, options], callback)
fs.rmSync(path[, options])
fs.stat(path[, options], callback)
fs.statSync(path[, options])
fs.symlink(target, path[, type], callback)
fs.symlinkSync(target, path[, type])
fs.truncate(path[, len], callback)
fs.truncateSync(path[, len])
fs.unlink(path, callback)
fs.unlinkSync(path)
fs.unwatchFile(filename[, listener])
fs.utimes(path, atime, mtime, callback)
fs.utimesSync(path, atime, mtime)
fs.watch(filename[, options][, listener])
fs.watchFile(filename[, options], listener)
fs.write(fd, buffer[, offset[, length[, position]]], callback)
fs.write(fd, string[, position[, encoding]], callback)
fs.writeFile(file, data[, options], callback)
fs.writeFileSync(file, data[, options])
fs.writeSync(fd, buffer[, offset[, length[, position]]])
fs.writeSync(fd, string[, position[, encoding]])
fs.writev(fd, buffers[, position], callback)
fs.writevSync(fd, buffers[, position])
- fs 的 Promise API
- FileHandle 类
filehandle.appendFile(data, options)
filehandle.chmod(mode)
filehandle.chown(uid, gid)
filehandle.close()
filehandle.datasync()
filehandle.fd
filehandle.read(buffer, offset, length, position)
filehandle.read(options)
filehandle.readFile(options)
filehandle.readv(buffers[, position])
filehandle.stat([options])
filehandle.sync()
filehandle.truncate(len)
filehandle.utimes(atime, mtime)
filehandle.write(buffer[, offset[, length[, position]]])
filehandle.write(string[, position[, encoding]])
filehandle.writeFile(data, options)
filehandle.writev(buffers[, position])
fsPromises.access(path[, mode])
fsPromises.appendFile(path, data[, options])
fsPromises.chmod(path, mode)
fsPromises.chown(path, uid, gid)
fsPromises.copyFile(src, dest[, mode])
fsPromises.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])
- FileHandle 类
fsPromises.rm(path[, options])
- FS 常量
- 文件系统标志
fs(文件系统)#
源代码: lib/fs.js
fs
模块可用于与文件系统进行交互(以类似于标准 POSIX 函数的方式)。
要使用此模块:
const fs = require('fs');
所有的文件系统操作都具有同步的、回调的、以及基于 promise 的形式。
同步的示例#
同步的形式会阻塞 Node.js 事件循环和进一步的 JavaScript 执行,直到操作完成。
异常会被立即地抛出,可以使用 try…catch
处理,也可以冒泡。
const fs = require('fs');
try {
fs.unlinkSync('文件');
console.log('已成功删除文件');
} catch (err) {
// 处理错误
}
回调的示例#
异步的形式总是把完成回调作为其最后一个参数。
传给完成回调的参数取决于具体方法,但第一个参数总是预留给异常。
如果操作被成功地完成,则第一个参数会为 null
或 undefined
。
const fs = require('fs');
fs.unlink('文件', (err) => {
if (err) throw err;
console.log('已成功删除文件');
});
Promise 的示例#
基于 promise 的操作会返回 Promise
(当异步操作完成时被解决)。
const fs = require('fs/promises');
(async function(path) {
try {
await fs.unlink(path);
console.log(`已成功删除 ${path}`);
} catch (error) {
console.error('出错:', error.message);
}
})('文件');
回调与基于 promise 的操作的顺序#
当使用异步的方法时,无法保证顺序。
因此,以下的操作容易出错,因为 fs.stat()
操作可能在 fs.rename()
操作之前完成:
fs.rename('旧文件', '新文件', (err) => {
if (err) throw err;
console.log('重命名完成');
});
fs.stat('新文件', (err, stats) => {
if (err) throw err;
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
若要正确地排序这些操作,则移动 fs.stat()
调用到 fs.rename()
操作的回调中:
fs.rename('旧文件', '新文件', (err) => {
if (err) throw err;
fs.stat('新文件', (err, stats) => {
if (err) throw err;
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
});
或者,使用基于 promise 的 API:
const fs = require('fs/promises');
(async function(from, to) {
try {
await fs.rename(from, to);
const stats = await fs.stat(to);
console.log(`文件属性: ${JSON.stringify(stats)}`);
} catch (error) {
console.error('出错:', error.message);
}
})('旧文件', '新文件');
文件路径#
大多数 fs
操作接受的文件路径可以指定为字符串、Buffer
、或 URL
对象(使用 file:
协议)。
字符串形式的路径会被解释为 UTF-8 字符序列(标识绝对或相对的文件名)。
相对路径会相对于当前工作目录(通过调用 process.cwd()
确定)进行处理。
在 POSIX 上使用绝对路径的示例:
const fs = require('fs');
fs.open('/文件.txt', 'r', (err, fd) => {
if (err) throw err;
fs.close(fd, (err) => {
if (err) throw err;
});
});
在 POSIX 上使用相对路径(相对于 process.cwd()
)的示例:
fs.open('文件.txt', 'r', (err, fd) => {
if (err) throw err;
fs.close(fd, (err) => {
if (err) throw err;
});
});
使用 Buffer
指定的路径主要用于将文件路径视为不透明字节序列的某些 POSIX 操作系统。
在这些系统上,单个文件路径可以包含使用多种字符编码的子序列。
与字符串路径一样, Buffer
路径也可以是相对或绝对的:
在 POSIX 上使用绝对路径的示例:
fs.open(Buffer.from('/文件.txt'), 'r', (err, fd) => {
if (err) throw err;
fs.close(fd, (err) => {
if (err) throw err;
});
});
在 Windows 上,Node.js 遵循独立驱动器工作目录的概念。
当使用没有反斜杠的驱动器路径时,可以观察到此行为。
例如, fs.readdirSync('C:\\')
可能会返回与 fs.readdirSync('C:')
不同的结果。
详见此 MSDN 页面。
URL 对象的支持#
对于大多数 fs
模块的函数, path
或 filename
参数可以传入 WHATWG URL
对象。
仅支持使用 file:
协议的 URL
对象。
const fs = require('fs');
const fileUrl = new URL('file:///文件');
fs.readFileSync(fileUrl);
file:
URL 始终是绝对路径。
使用 WHATWG URL
对象可能会采用特定于平台的行为。
在 Windows 上,带有主机名的 file:
URL 会转换为 UNC 路径,而带有驱动器号的 file:
URL 会转换为本地的绝对路径。
没有主机名和驱动器号的 file:
URL 会导致抛出错误:
// 在 Windows 上:
// - 带有主机名的 WHATWG 文件的 URL 会转换为 UNC 路径。
// file://主机名/文件 => \\主机名\文件
fs.readFileSync(new URL('file://主机名/文件'));
// - 带有驱动器号的 WHATWG 文件的 URL 会转换为绝对路径。
// file:///C:/文件 => C:\文件
fs.readFileSync(new URL('file:///C:/文件'));
// - 没有主机名的 WHATWG 文件的 URL 必须包含驱动器号。
fs.readFileSync(new URL('file:///无驱动器号/文件'));
fs.readFileSync(new URL('file:///文件'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
带有驱动器号的 file:
URL 必须使用 :
作为驱动器号后面的分隔符。
使用其他分隔符会导致抛出错误。
在所有其他平台上,不支持带有主机名的 file:
URL,使用时会导致抛出错误:
// 在其他平台上:
// - 不支持带有主机名的 WHATWG 文件的 URL。
// file://主机名/文件 => 抛出错误!
fs.readFileSync(new URL('file://主机名/文件'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
// - WHATWG 文件的 URL 会转换为绝对路径。
// file:///文件 => /文件
fs.readFileSync(new URL('file:///文件'));
包含编码后的斜杆字符的 file:
URL 在所有平台上都会导致抛出错误:
// 在 Windows 上:
fs.readFileSync(new URL('file:///C:/%2F'));
fs.readFileSync(new URL('file:///C:/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */
// 在 POSIX 上:
fs.readFileSync(new URL('file:///%2F'));
fs.readFileSync(new URL('file:///%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
/ characters */
在 Windows 上,包含编码后的反斜杆字符的 file:
URL 会导致抛出错误:
// 在 Windows 上:
fs.readFileSync(new URL('file:///C:/%5C'));
fs.readFileSync(new URL('file:///C:/%5c'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */
文件描述符#
在 POSIX 系统上,对于每个进程,内核都维护着一张当前打开着的文件和资源的表格。 每个打开的文件都分配了一个称为文件描述符的简单的数字标识符。 在系统层,所有文件系统操作都使用这些文件描述符来标识和跟踪每个特定的文件。 Windows 系统使用了一个虽然不同但概念上类似的机制来跟踪资源。 为了简化用户的工作,Node.js 抽象出操作系统之间的特定差异,并为所有打开的文件分配一个数字型的文件描述符。
fs.open()
方法用于分配新的文件描述符。
一旦被分配,则文件描述符可用于从文件读取数据、向文件写入数据、或请求关于文件的信息。
fs.open('/open/some/file.txt', 'r', (err, fd) => {
if (err) throw err;
fs.fstat(fd, (err, stat) => {
if (err) throw err;
// 使用文件属性。
// 始终关闭文件描述符!
fs.close(fd, (err) => {
if (err) throw err;
});
});
});
大多数操作系统限制在任何给定时间内可能打开的文件描述符的数量,因此当操作完成时关闭描述符至关重要。 如果不这样做将导致内存泄漏,最终导致应用程序崩溃。
线程池的使用#
所有的文件系统 API,除了 fs.FSWatcher()
和那些显式同步的之外,都使用 libuv 的线程池,这对某些应用程序可能会产生意外和负面的性能影响。
有关更多信息,参见 UV_THREADPOOL_SIZE
文档。
fs.Dir 类#
表示目录流的类。
由 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
创建。
const fs = require('fs');
async function print(path) {
const dir = await fs.promises.opendir(path);
for await (const dirent of dir) {
console.log(dirent.name);
}
}
print('./').catch(console.error);
dir.close()
#
- 返回: <Promise>
异步地关闭目录的底层资源句柄。 后续的读取会导致错误。
返回 Promise
(在资源被关闭之后会被 resolve)。
dir.close(callback)
#
callback
<Function>err
<Error>
异步地关闭目录的底层资源句柄。 后续的读取会导致错误。
关闭资源句柄之后将会调用 callback
。
dir.closeSync()
#
同步地关闭目录的底层资源句柄。 后续的读取会导致错误。
dir.path
#
此目录的只读路径,与提供给 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
的一样。
dir.read()
#
- 返回: 包含 <fs.Dirent> | <null> 的 <Promise>
通过 readdir(3)
异步地读取下一个目录项作为 fs.Dirent
。
读取完成之后,则会返回 Promise
(resolve 时会传入 fs.Dirent
或 null
(如果读取不到目录项))。
此函数返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能不会包含在遍历的结果中。
dir.read(callback)
#
callback
<Function>err
<Error>dirent
<fs.Dirent> | <null>
通过 readdir(3)
异步地读取下一个目录项作为 fs.Dirent
。
读取完成之后,则会调用 callback
(传入 fs.Dirent
或 null
(如果读取不到目录项))。
此函数返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能不会包含在遍历的结果中。
dir.readSync()
#
- 返回: <fs.Dirent> | <null>
通过 readdir(3)
同步地读取下一个目录项作为 fs.Dirent
。
如果读取不到目录项,则将会返回 null
。
此函数返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能不会包含在遍历的结果中。
dir[Symbol.asyncIterator]()
#
- 返回: <fs.Dirent> 的 <AsyncIterator>
通过 readdir(3)
异步地遍历目录,直到读取了所有的目录项。
异步迭代器返回的目录项始终为 fs.Dirent
。
dir.read()
中为 null
的情况会在内部处理。
有关示例,请参见 fs.Dir
。
该迭代器返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能不会包含在遍历的结果中。
fs.Dirent 类#
目录项(可以是文件或目录中的子目录)的表示,通过读取 fs.Dir
返回。
目录项是文件名和文件类型对的组合。
此外,当调用 fs.readdir()
或 fs.readdirSync()
(withFileTypes
选项设置为 true
)时,则生成的数组会使用 fs.Dirent
对象(而不是字符串或 Buffer
)填充。
dirent.isBlockDevice()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述块设备,则返回 true
。
dirent.isCharacterDevice()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述字符设备,则返回 true
。
dirent.isDirectory()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述文件系统目录,则返回 true
。
dirent.isFIFO()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述先进先出(FIFO)管道,则返回 true
。
dirent.isFile()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述普通的文件,则返回 true
。
dirent.isSocket()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述套接字,则返回 true
。
dirent.isSymbolicLink()
#
- 返回: <boolean>
如果 fs.Dirent
对象描述符号链接,则返回 true
。
dirent.name
#
fs.Dirent
对象指向的文件名。
此值的类型取决于传递给 fs.readdir()
或 fs.readdirSync()
的 options.encoding
。
fs.FSWatcher 类#
- 继承自 <EventEmitter>
成功调用 fs.watch()
方法会返回新建的 fs.FSWatcher
对象。
每当指定监视的文件被修改时,所有的 fs.FSWatcher
对象都会触发 'change'
事件。
'change' 事件#
当监视的目录或文件中发生更改时触发。
在 fs.watch()
中查看更多详细信息。
可能不提供 filename
参数,这取决于操作系统的支持。
如果提供了 filename
,则当调用 fs.watch()
并将其 encoding
选项设置为 'buffer'
时, filename
将是一个 Buffer
,否则 filename
将是 UTF-8 字符串。
// 使用 fs.watch()监听器的示例。
fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => {
if (filename) {
console.log(filename);
// 打印: <Buffer ...>
}
});
'close' 事件#
当监视器停止监视更改时触发。
关闭的 fs.FSWatcher
对象在事件处理函数中不再可用。
'error' 事件#
error
<Error>
当监视文件时发生错误时触发。
发生错误的 fs.FSWatcher
对象在事件处理函数中不再可用。
watcher.close()
#
给定的 fs.FSWatcher
停止监视更改。
一旦停止,则 fs.FSWatcher
对象将不再可用。
watcher.ref()
#
- Returns: <fs.FSWatcher>
When called, requests that the Node.js event loop not exit so long as the
FSWatcher
is active. Calling watcher.ref()
multiple times will have
no effect.
By default, all FSWatcher
objects are "ref'ed", making it normally
unnecessary to call watcher.ref()
unless watcher.unref()
had been
called previously.
watcher.unref()
#
- Returns: <fs.FSWatcher>
When called, the active FSWatcher
object will not require the Node.js
event loop to remain active. If there is no other activity keeping the
event loop running, the process may exit before the FSWatcher
object's
callback is invoked. Calling watcher.unref()
multiple times will have
no effect.
fs.StatWatcher 类#
- Extends <EventEmitter>
A successful call to fs.watchFile()
method will return a new fs.StatWatcher
object.
watcher.ref()
#
- Returns: <fs.StatWatcher>
When called, requests that the Node.js event loop not exit so long as the
StatWatcher
is active. Calling watcher.ref()
multiple times will have
no effect.
By default, all StatWatcher
objects are "ref'ed", making it normally
unnecessary to call watcher.ref()
unless watcher.unref()
had been
called previously.
watcher.unref()
#
- Returns: <fs.StatWatcher>
When called, the active StatWatcher
object will not require the Node.js
event loop to remain active. If there is no other activity keeping the
event loop running, the process may exit before the StatWatcher
object's
callback is invoked. Calling watcher.unref()
multiple times will have
no effect.
fs.ReadStream 类#
- 继承自: <stream.Readable>
使用 fs.createReadStream()
函数创建并返回的 fs.ReadStream
实例。
'close' 事件#
当 fs.ReadStream
的底层文件描述符已关闭时触发。
'open' 事件#
fd
<integer>ReadStream
使用的整数型文件描述符。
当 fs.ReadStream
的文件描述符打开时触发。
'ready' 事件#
当 fs.ReadStream
准备好使用时触发。
'open'
事件之后立即触发。
readStream.bytesRead
#
到目前为止已读取的字节数。
readStream.path
#
流正在读取的文件的路径,由 fs.createReadStream()
的第一个参数指定。
如果 path
传入字符串,则 readStream.path
将是字符串。
如果 path
传入 Buffer
,则 readStream.path
将是 Buffer
。
readStream.pending
#
如果底层的文件还未被打开(即在触发 'ready'
事件之前),则此属性为 true
。
fs.Stats 类#
fs.Stats
对象提供了关于文件的信息。
从 fs.stat()
、fs.lstat()
、fs.fstat()
、以及它们的同步方法返回的对象都是此类型。
如果传给这些方法的 options
中的 bigint
为 true,则数值会是 bigint
型而不是 number
型,并且该对象还会包含额外的纳秒级精度的属性(以 Ns
为后缀)。
Stats {
dev: 2114,
ino: 48064969,
mode: 33188,
nlink: 1,
uid: 85,
gid: 100,
rdev: 0,
size: 527,
blksize: 4096,
blocks: 8,
atimeMs: 1318289051000.1,
mtimeMs: 1318289051000.1,
ctimeMs: 1318289051000.1,
birthtimeMs: 1318289051000.1,
atime: Mon, 10 Oct 2011 23:24:11 GMT,
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
ctime: Mon, 10 Oct 2011 23:24:11 GMT,
birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
bigint
的版本:
BigIntStats {
dev: 2114n,
ino: 48064969n,
mode: 33188n,
nlink: 1n,
uid: 85n,
gid: 100n,
rdev: 0n,
size: 527n,
blksize: 4096n,
blocks: 8n,
atimeMs: 1318289051000n,
mtimeMs: 1318289051000n,
ctimeMs: 1318289051000n,
birthtimeMs: 1318289051000n,
atimeNs: 1318289051000000000n,
mtimeNs: 1318289051000000000n,
ctimeNs: 1318289051000000000n,
birthtimeNs: 1318289051000000000n,
atime: Mon, 10 Oct 2011 23:24:11 GMT,
mtime: Mon, 10 Oct 2011 23:24:11 GMT,
ctime: Mon, 10 Oct 2011 23:24:11 GMT,
birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
stats.isBlockDevice()
#
- 返回: <boolean>
如果 fs.Stats
对象描述块设备,则返回 true
。
stats.isCharacterDevice()
#
- 返回: <boolean>
如果 fs.Stats
对象描述字符设备,则返回 true
。
stats.isDirectory()
#
- 返回: <boolean>
如果 fs.Stats
对象描述文件系统目录,则返回 true
。
stats.isFIFO()
#
- 返回: <boolean>
如果 fs.Stats
对象描述先进先出(FIFO)管道,则返回 true
。
stats.isFile()
#
- 返回: <boolean>
如果 fs.Stats
对象描述普通的文件,则返回 true
。
stats.isSocket()
#
- 返回: <boolean>
如果 fs.Stats
对象描述套接字,则返回 true
。
stats.isSymbolicLink()
#
- 返回: <boolean>
如果 fs.Stats
对象描述符号链接,则返回 true
。
此方法仅在使用 fs.lstat()
时有效。
stats.dev
#
包含该文件的设备的数字标识符。
stats.ino
#
文件系统特定的文件索引节点编号。
stats.mode
#
描述文件类型和模式的位字段。
stats.nlink
#
文件存在的硬链接数。
stats.uid
#
拥有该文件(POSIX)的用户的数字型用户标识符。
stats.gid
#
拥有该文件(POSIX)的群组的数字型群组标识符。
stats.rdev
#
如果文件表示一个设备,则此值为数字型设备标识符。
stats.size
#
文件的大小(以字节为单位)。
stats.blksize
#
用于 I/O 操作的文件系统块的大小。
stats.blocks
#
为此文件分配的块数。
stats.atimeMs
#
表明上次访问此文件的时间戳,以 POSIX 纪元以来的毫秒数表示。
stats.mtimeMs
#
表明上次修改此文件的时间戳,以 POSIX 纪元以来的毫秒数表示。
stats.ctimeMs
#
表明上次更改文件状态的时间戳,以 POSIX 纪元以来的毫秒数表示。
stats.birthtimeMs
#
表明此文件的创建时间的时间戳,以 POSIX 纪元以来的毫秒数表示。
stats.atimeNs
#
Only present when bigint: true
is passed into the method that generates
the object.
The timestamp indicating the last time this file was accessed expressed in
nanoseconds since the POSIX Epoch.
stats.mtimeNs
#
Only present when bigint: true
is passed into the method that generates
the object.
The timestamp indicating the last time this file was modified expressed in
nanoseconds since the POSIX Epoch.
stats.ctimeNs
#
Only present when bigint: true
is passed into the method that generates
the object.
The timestamp indicating the last time the file status was changed expressed
in nanoseconds since the POSIX Epoch.
stats.birthtimeNs
#
Only present when bigint: true
is passed into the method that generates
the object.
The timestamp indicating the creation time of this file expressed in
nanoseconds since the POSIX Epoch.
stats.atime
#
表明上次访问此文件的时间戳。
stats.mtime
#
表明上次修改此文件的时间戳。
stats.ctime
#
表明上次更改文件状态的时间戳。
stats.birthtime
#
表示此文件的创建时间的时间戳。
文件属性的时间值#
atimeMs
、 mtimeMs
、 ctimeMs
和 birthtimeMs
属性是保存相应时间(以毫秒为单位)的数值。
它们的精度取决于平台。
当将 bigint: true
传给生成该对象的方法时,属性将会是 bigint 型,否则它们将会是数字型。
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
"更改时间" - 上次更改文件状态(修改索引节点数据)的时间。由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 之前,在 Windows 系统上 ctime
保存 birthtime
。
从 0.12 开始, ctime
不再是“创建时间”,而在 Unix 系统上则从来都不是。
fs.WriteStream 类#
使用 fs.createWriteStream()
函数创建并返回的 fs.WriteStream
实例。
'close' 事件#
当 WriteStream
的底层文件描述符已关闭时触发。
'open' 事件#
fd
<integer>WriteStream
使用的整数型文件描述符。
当 WriteStream
的文件打开时触发。
'ready' 事件#
当 fs.WriteStream
准备好使用时触发。
'open'
事件之后立即触发。
writeStream.bytesWritten
#
到目前为止写入的字节数。 不包括仍在排队等待写入的数据。
writeStream.path
#
流正在写入的文件的路径,由 fs.createWriteStream()
的第一个参数指定。
如果 path
传入字符串,则 writeStream.path
将是字符串。
如果 path
传入 Buffer
,则 writeStream.path
将是 Buffer
。
writeStream.pending
#
如果底层的文件还未被打开(即在触发 'ready'
事件之前),则此属性为 true
。
fs.access(path[, mode], callback)
#
path
<string> | <Buffer> | <URL>mode
<integer> 默认值:fs.constants.F_OK
。callback
<Function>err
<Error>
测试用户对 path
指定的文件或目录的权限。
mode
参数是一个可选的整数,指定要执行的可访问性检查。
查看文件可访问性的常量了解 mode
的可选值。
可以创建由两个或更多个值按位或组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK
)。
最后一个参数 callback
是回调函数,调用时会传入可能的错误参数。
如果任何可访问性检查失败,则错误参数会是 Error
对象。
以下示例会检查 package.json
是否存在、以及是否可读或可写。
const file = 'package.json';
// 检查文件是否存在于当前目录中。
fs.access(file, fs.constants.F_OK, (err) => {
console.log(`${file} ${err ? '不存在' : '存在'}`);
});
// 检查文件是否可读。
fs.access(file, fs.constants.R_OK, (err) => {
console.log(`${file} ${err ? '不可读' : '可读'}`);
});
// 检查文件是否可写。
fs.access(file, fs.constants.W_OK, (err) => {
console.log(`${file} ${err ? '不可写' : '可写'}`);
});
// 检查文件是否存在于当前目录中、以及是否可写。
fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
if (err) {
console.error(
`${file} ${err.code === 'ENOENT' ? '不存在' : '只可读'}`);
} else {
console.log(`${file} 存在,且可写`);
}
});
不要在调用 fs.open()
、 fs.readFile()
或 fs.writeFile()
之前使用 fs.access()
检查文件的可访问性。
这样做会引入竞态条件,因为其他进程可能会在两个调用之间更改文件的状态。
而是,应该直接打开、读取或写入文件,并且当文件无法访问时处理引发的错误。
写入(不推荐)
fs.access('文件', (err) => {
if (!err) {
console.error('文件已存在');
return;
}
fs.open('文件', 'wx', (err, fd) => {
if (err) throw err;
writeMyData(fd);
});
});
写入(推荐)
fs.open('文件', 'wx', (err, fd) => {
if (err) {
if (err.code === 'EEXIST') {
console.error('文件已存在');
return;
}
throw err;
}
writeMyData(fd);
});
读取(不推荐)
fs.access('文件', (err) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('文件不存在');
return;
}
throw err;
}
fs.open('文件', 'r', (err, fd) => {
if (err) throw err;
readMyData(fd);
});
});
读取(推荐)
fs.open('文件', 'r', (err, fd) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('文件不存在');
return;
}
throw err;
}
readMyData(fd);
});
上面的“不推荐”示例会先检查可访问性,然后再使用文件。 “推荐”示例则更好,因为它们直接使用文件并处理错误(如果有错误的话)。
通常,仅在不直接使用文件时(例如当其可访问性是来自其他进程的信号时),才检查文件的可访问性。
在 Windows 上,目录上的访问控制策略(ACL)可能会限制对文件或目录的访问。
但是, fs.access()
函数不检查 ACL,因此即使 ACL 限制用户读取或写入,也可能报告路径是可访问的。
fs.accessSync(path[, mode])
#
同步地测试用户对 path
指定的文件或目录的权限。
mode
参数是一个可选的整数,指定要执行的可访问性检查。
查看文件可访问性的常量了解 mode
的可选值。
可以创建由两个或更多个值按位或组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK
)。
如果可访问性检查失败,则抛出 Error
。
否则,该方法将返回 undefined
。
try {
fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);
console.log('可以读写');
} catch (err) {
console.error('无权访问');
}
fs.appendFile(path, data[, options], callback)
#
path
<string> | <Buffer> | <URL> | <number> 文件名或文件描述符。data
<string> | <Buffer>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
。mode
<integer> 默认值:0o666
。flag
<string> 参见文件系统flag
的支持。默认值:'a'
。
callback
<Function>err
<Error>
异步地追加数据到文件,如果文件尚不存在则创建文件。
data
可以是字符串或 Buffer
。
fs.appendFile('文件.txt', '追加的数据', (err) => {
if (err) throw err;
console.log('数据已被追加到文件');
});
如果 options
是字符串,则它指定字符编码:
fs.appendFile('文件.txt', '追加的数据', 'utf8', callback);
path
可以指定为已打开用于追加(使用 fs.open()
或 fs.openSync()
)的数字型文件描述符。
文件描述符不会自动关闭。
fs.open('文件.txt', 'a', (err, fd) => {
if (err) throw err;
fs.appendFile(fd, '追加的数据', 'utf8', (err) => {
fs.close(fd, (err) => {
if (err) throw err;
});
if (err) throw err;
});
});
fs.appendFileSync(path, data[, options])
#
path
<string> | <Buffer> | <URL> | <number> 文件名或文件描述符。data
<string> | <Buffer>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
。mode
<integer> 默认值:0o666
。flag
<string> 参见文件系统flag
的支持。默认值:'a'
。
同步地将数据追加到文件,如果文件尚不存在则创建该文件。
data
可以是字符串或 Buffer
。
try {
fs.appendFileSync('文件.txt', '追加的数据');
console.log('数据已被追加到文件');
} catch (err) {
/* 处理错误 */
}
如果 options
是字符串,则它指定字符编码:
fs.appendFileSync('文件.txt', '追加的数据', 'utf8');
path
可以指定为已打开用于追加(使用 fs.open()
或 fs.openSync()
)的数字型文件描述符。
文件描述符不会自动关闭。
let fd;
try {
fd = fs.openSync('文件.txt', 'a');
fs.appendFileSync(fd, '追加的数据', 'utf8');
} catch (err) {
/* 处理错误 */
} finally {
if (fd !== undefined)
fs.closeSync(fd);
}
fs.chmod(path, mode, callback)
#
异步地更改文件的权限。 除了可能的异常,完成回调没有其他参数。
也可参见 chmod(2)
。
fs.chmod('my_file.txt', 0o775, (err) => {
if (err) throw err;
console.log('文件 “my_file.txt” 的权限已被更改');
});
文件的模式#
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.chmodSync(path, mode)
#
详见此 API 的异步版本的文档:fs.chmod()
。
也可参见 chmod(2)
。
fs.chown(path, uid, gid, callback)
#
异步地更改文件的所有者和群组。 除了可能的异常,完成回调没有其他参数。
也可参见 chown(2)
。
fs.chownSync(path, uid, gid)
#
同步地更改文件的所有者和群组。
返回 undefined
。
这是 fs.chown()
的同步版本。
也可参见 chown(2)
。
fs.close(fd, callback)
#
fd
<integer>callback
<Function>err
<Error>
异步的 close(2)
。
除了可能的异常,完成回调没有其他参数。
通过任何其他 fs
操作在当前正在使用的任何文件描述符(fd
)上调用 fs.close()
可能导致未定义的行为。
fs.closeSync(fd)
#
fd
<integer>
同步的 close(2)
。返回 undefined
。
通过任何其他 fs
操作在当前正在使用的任何文件描述符(fd
)上调用 fs.closeSync()
可能导致未定义的行为。
fs.constants
#
返回包含文件系统操作常用常量的对象。 当前定义的特定常量在 FS 常量中描述。
fs.copyFile(src, dest[, mode], callback)
#
src
<string> | <Buffer> | <URL> 要拷贝的源文件名。dest
<string> | <Buffer> | <URL> 拷贝操作的目标文件名。mode
<integer> 用于拷贝操作的修饰符。默认值:0
。callback
<Function>
异步地将 src
拷贝到 dest
。
默认情况下,如果 dest
已经存在,则覆盖它。
除了可能的异常,回调函数没有其他参数。
Node.js 不保证拷贝操作的原子性。
如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
mode
是一个可选的整数,指定拷贝操作的行为。
可以创建由两个或更多个值按位或组成的掩码(比如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE
)。
fs.constants.COPYFILE_EXCL
- 如果dest
已存在,则拷贝操作将失败。fs.constants.COPYFILE_FICLONE
- 拷贝操作将尝试创建写时拷贝(copy-on-write)链接。如果平台不支持写时拷贝,则使用后备的拷贝机制。fs.constants.COPYFILE_FICLONE_FORCE
- 拷贝操作将尝试创建写时拷贝链接。如果平台不支持写时拷贝,则拷贝操作将失败。
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;
function callback(err) {
if (err) throw err;
console.log('源文件已拷贝到目标文');
}
// 默认情况下将创建或覆盖目标文件。
fs.copyFile('源文件.txt', '目标文件.txt', callback);
// 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
fs.copyFile('源文件.txt', '目标文件.txt', COPYFILE_EXCL, callback);
fs.copyFileSync(src, dest[, mode])
#
src
<string> | <Buffer> | <URL> 要拷贝的源文件名。dest
<string> | <Buffer> | <URL> 拷贝操作的目标文件名。mode
<integer> 用于拷贝操作的修饰符。默认值:0
。
同步地将 src
拷贝到 dest
。
默认情况下,如果 dest
已经存在,则覆盖它。
返回 undefined
。
Node.js 不保证拷贝操作的原子性。
如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
mode
是一个可选的整数,指定拷贝操作的行为。
可以创建由两个或更多个值按位或组成的掩码(比如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE
)。
fs.constants.COPYFILE_EXCL
- 如果dest
已存在,则拷贝操作将失败。fs.constants.COPYFILE_FICLONE
- 拷贝操作将尝试创建写时拷贝(copy-on-write)链接。如果平台不支持写时拷贝,则使用后备的拷贝机制。fs.constants.COPYFILE_FICLONE_FORCE
- 拷贝操作将尝试创建写时拷贝链接。如果平台不支持写时拷贝,则拷贝操作将失败。
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;
// 默认情况下将创建或覆盖目标文件。
fs.copyFileSync('源文件.txt', '目标文件.txt');
console.log('源文件已拷贝到目标文件');
// 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
fs.copyFileSync('源文件.txt', '目标文件.txt', COPYFILE_EXCL);
fs.createReadStream(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>flags
<string> 参见文件系统flag
的支持。 默认值:'r'
。encoding
<string> 默认值:null
。fd
<integer> 默认值:null
。mode
<integer> 默认值:0o666
。autoClose
<boolean> 默认值:true
。emitClose
<boolean> 默认值:false
。start
<integer>end
<integer> 默认值:Infinity
。highWaterMark
<integer> 默认值:64 * 1024
。fs
<Object> | <null> 默认值:null
。
- 返回: <fs.ReadStream> 参见可读流。
与可读流的 16 kb 的默认 highWaterMark
不同,此方法返回的流具有 64 kb 的默认 highWaterMark
。
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'
事件。
这与其他 Readable
流的默认设置是相反的。
设置 emitClose
选项为 true
可以更改此行为。
通过提供 fs
选项,可以重写对应的 fs
实现(用于 open
、 read
和 close
)。
当提供 fs
选项时,则必须重写 open
、 read
和 close
。
const fs = require('fs');
// 从某个字符设备创建流。
const stream = fs.createReadStream('设备');
setTimeout(() => {
stream.close(); // 这可能不会关闭流。
// 手动标记流的结束,就像底层的资源自身已表明文件的结束一样,使得流可以关闭。
// 这不会取消待处理的读取操作,如果存在此类操作,则进程可能仍无法成功地退出,直到完成。
stream.push(null);
stream.read(0);
}, 100);
如果 autoClose
为 false,则即使发生错误,文件描述符也不会被关闭。
应用程序需要负责关闭它并确保没有文件描述符泄漏。
如果 autoClose
被设置为 true(默认的行为),则当 'error'
或 'end'
事件时,文件描述符会被自动地关闭。
mode
用于设置文件模式(权限和粘滞位),但仅限于文件被创建时。
示例,读取文件(长度为 100 个字节)的最后 10 个字节:
fs.createReadStream('文件', { start: 90, end: 99 });
如果 options
是字符串,则它指定字符编码。
fs.createWriteStream(path[, options])
#
options
还可以包括 start
选项,用于写入数据到文件开头之后的某个位置,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 的范围内。
若要修改文件而不是覆盖文件,则需要 flags
选项被设置为 r+
而不是默认的 w
。
encoding
可以是能被 Buffer
接受的任何一种字符编码。
如果 autoClose
被设置为 true(默认的行为),则当 'error'
或 'finish'
事件时,文件描述符会被自动地关闭。
如果 autoClose
为 false,则即使发生错误,文件描述符也不会被关闭。
应用程序需要负责关闭它并确保没有文件描述符泄漏。
默认情况下,流被销毁之后不会触发 'close'
事件。
这与其他 Writable
流的默认设置是相反的。
设置 emitClose
选项为 true
可以更改此行为。
通过提供 fs
选项,可以重写对应的 fs
实现(用于 open
、 write
、 writev
和 close
)。
如果重写 write()
但没有重写 writev()
,则会降低性能,因为某些优化(_writev()
)会被禁用。
当提供 fs
选项时,则必须重写 open
、 close
、以及 write
和 writev
两者至少其中之一。
与 ReadStream
一样,如果指定了 fd
,则 WriteStream
会忽略 path
参数,并且会使用指定的文件描述符。
这意味着不会触发 'open'
事件。
fd
必须是阻塞的,非阻塞的 fd
应该传给 net.Socket
。
如果 options
是字符串,则它指定字符编码。
fs.exists(path, callback)
#
path
<string> | <Buffer> | <URL>callback
<Function>exists
<boolean>
通过检查文件系统来测试给定的路径是否存在。
然后调用 callback
并带上参数 true
或 false
:
fs.exists('/etc/passwd', (exists) => {
console.log(exists ? '存在' : '不存在');
});
此回调的参数与其他 Node.js 回调不一致。
通常,Node.js 回调的第一个参数是 err
参数,后面可选地跟随其他参数。
fs.exists()
的回调只有一个布尔值参数。
这是推荐 fs.access()
代替 fs.exists()
的原因之一。
不建议在调用 fs.open()
、 fs.readFile()
或 fs.writeFile()
之前使用 fs.exists()
检查文件是否存在。
这样做会引入竞态条件,因为其他进程可能会在两次调用之间更改文件的状态。
相反,应该直接打开、读取或写入文件,如果文件不存在则处理引发的错误。
写入(不推荐)
fs.exists('myfile', (exists) => {
if (exists) {
console.error('myfile 已存在');
} else {
fs.open('myfile', 'wx', (err, fd) => {
if (err) throw err;
writeMyData(fd);
});
}
});
写入(推荐)
fs.open('myfile', 'wx', (err, fd) => {
if (err) {
if (err.code === 'EEXIST') {
console.error('myfile 已存在');
return;
}
throw err;
}
writeMyData(fd);
});
读取(不推荐)
fs.exists('myfile', (exists) => {
if (exists) {
fs.open('myfile', 'r', (err, fd) => {
if (err) throw err;
readMyData(fd);
});
} else {
console.error('myfile 不存在');
}
});
读取(推荐)
fs.open('myfile', 'r', (err, fd) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('myfile 不存在');
return;
}
throw err;
}
readMyData(fd);
});
上面的“不推荐”示例会先检查文件是否存在然后再使用该文件。 “推荐”示例则更好,因为它们直接使用文件并处理错误(如果有错误的话)。
通常,仅在文件不直接使用时才检查文件是否存在,例如当其存在性是来自另一个进程的信号时。
fs.existsSync(path)
#
如果路径存在,则返回 true
,否则返回 false
。
详见此 API 的异步版本的文档:fs.exists()
。
虽然 fs.exists()
是弃用的,但 fs.existsSync()
不是弃用的。
fs.exists()
的 callback
参数接受的参数与其他的 Node.js 回调的不一致。
fs.existsSync()
不使用回调。
if (fs.existsSync('文件')) {
console.log('路径已存在');
}
fs.fchmod(fd, mode, callback)
#
fd
<integer>mode
<string> | <integer>callback
<Function>err
<Error>
异步的 fchmod(2)
。
除了可能的异常,完成回调没有其他参数。
fs.fchmodSync(fd, mode)
#
同步的 fchmod(2)
。返回 undefined
。
fs.fchown(fd, uid, gid, callback)
#
fd
<integer>uid
<integer>gid
<integer>callback
<Function>err
<Error>
异步的 fchown(2)
。
除了可能的异常,完成回调没有其他参数。
fs.fchownSync(fd, uid, gid)
#
同步的 fchown(2)
。返回 undefined
。
fs.fdatasync(fd, callback)
#
fd
<integer>callback
<Function>err
<Error>
异步的 fdatasync(2)
。
除了可能的异常,完成回调没有其他参数。
fs.fdatasyncSync(fd)
#
fd
<integer>
同步的 fdatasync(2)
。返回 undefined
。
fs.fstat(fd[, options], callback)
#
fd
<integer>options
<Object>callback
<Function>err
<Error>stats
<fs.Stats>
异步的 fstat(2)
。
回调会传入两个参数 (err, stats)
,其中 stats
是 fs.Stats
对象。
fstat()
与 stat()
相同,除了文件是由文件描述符 fd
指定。
fs.fstatSync(fd[, options])
#
fd
<integer>options
<Object>- 返回: <fs.Stats>
同步的 fstat(2)
。
fs.fsync(fd, callback)
#
fd
<integer>callback
<Function>err
<Error>
异步的 fsync(2)
。
除了可能的异常,完成回调没有其他参数。
fs.fsyncSync(fd)
#
fd
<integer>
同步的 fsync(2)
。返回 undefined
。
fs.ftruncate(fd[, len], callback)
#
fd
<integer>len
<integer> 默认值:0
。callback
<Function>err
<Error>
异步的 ftruncate(2)
。
除了可能的异常,完成回调没有其他参数。
如果文件描述符指向的文件大于 len
个字节,则只有前面 len
个字节会保留在文件中。
例如,以下程序只保留文件的前 4 个字节:
console.log(fs.readFileSync('temp.txt', 'utf8'));
// 打印: Node.js
// 获取要截断的文件的文件描述符。
const fd = fs.openSync('temp.txt', 'r+');
// 将文件截断为前 4 个字节。
fs.ftruncate(fd, 4, (err) => {
assert.ifError(err);
console.log(fs.readFileSync('temp.txt', 'utf8'));
});
// 打印: Node
如果文件小于 len
个字节,则会对其进行扩展,并且扩展部分将填充空字节('\0'
):
console.log(fs.readFileSync('temp.txt', 'utf8'));
// 打印: Node.js
// 获取要截断的文件的文件描述符。
const fd = fs.openSync('temp.txt', 'r+');
// 将文件截断为前 10 个字节,但实际大小为 7 个字节。
fs.ftruncate(fd, 10, (err) => {
assert.ifError(err);
console.log(fs.readFileSync('temp.txt'));
});
// 打印: <Buffer 4e 6f 64 65 2e 6a 73 00 00 00>
// (UTF8 的值为 'Node.js\0\0\0')
最后 3 个字节是空字节('\0'
),以补充超出的截断。
fs.ftruncateSync(fd[, len])
#
返回 undefined
。
有关详细信息,请参见此API的异步版本的文档:fs.ftruncate()
。
fs.futimes(fd, atime, mtime, callback)
#
fd
<integer>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>callback
<Function>err
<Error>
更改文件描述符指向的对象的文件系统时间戳。
参见 fs.utimes()
。
此函数在 7.1 之前的 AIX 版本上不起作用,它将返回 UV_ENOSYS
错误。
fs.futimesSync(fd, atime, mtime)
#
fs.futimes()
的同步版本。返回 undefined
。
fs.lchmod(path, mode, callback)
#
异步的 lchmod(2)
。
除了可能的异常,完成回调没有其他参数。
仅适用于 macOS。
fs.lchmodSync(path, mode)
#
同步的 lchmod(2)
。返回 undefined
。
fs.lchown(path, uid, gid, callback)
#
异步的 lchown(2)
。
除了可能的异常,完成回调没有其他参数。
fs.lchownSync(path, uid, gid)
#
同步的 lchown(2)
。返回 undefined
。
fs.lutimes(path, atime, mtime, callback)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>callback
<Function>err
<Error>
Changes the access and modification times of a file in the same way as
fs.utimes()
, with the difference that if the path refers to a symbolic
link, then the link is not dereferenced: instead, the timestamps of the
symbolic link itself are changed.
No arguments other than a possible exception are given to the completion callback.
fs.lutimesSync(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>
Change the file system timestamps of the symbolic link referenced by path
.
Returns undefined
, or throws an exception when parameters are incorrect or
the operation fails. This is the synchronous version of fs.lutimes()
.
fs.link(existingPath, newPath, callback)
#
existingPath
<string> | <Buffer> | <URL>newPath
<string> | <Buffer> | <URL>callback
<Function>err
<Error>
异步的 link(2)
。
除了可能的异常,完成回调没有其他参数。
fs.linkSync(existingPath, newPath)
#
同步的 link(2)
。返回 undefined
。
fs.lstat(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>callback
<Function>err
<Error>stats
<fs.Stats>
异步的 lstat(2)
。
回调会传入两个参数 (err, stats)
,其中 stats
是 fs.Stats
对象。
lstat()
与 stat()
相同,只是如果 path
是符号链接,则查看的是链接自身,而不是它指向的文件。
fs.lstatSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>- 返回: <fs.Stats>
同步的 lstat(2)
。
fs.mkdir(path[, options], callback)
#
异步地创建目录。
回调会传入可能的异常、以及创建的第一个目录的路径(如果 recursive
为 true
), (err, [path])
。
可选的 options
参数可以是整数(指定 mode
(权限和粘滞位))、或对象(具有 mode
属性和 recursive
属性(指示是否要创建父目录))。
当 path
是已存在的目录时,调用 fs.mkdir()
仅在 recursive
为 false 时才会导致错误。
// 创建 `/目录1/目录2/目录3`,不管 `/目录1` 和 `/目录1/目录2` 是否存在。
fs.mkdir('/目录1/目录2/目录3', { recursive: true }, (err) => {
if (err) throw err;
});
在 Windows 上,对根目录使用 fs.mkdir()
(即使使用遍历)也会导致错误:
fs.mkdir('/', { recursive: true }, (err) => {
// => [Error: EPERM: operation not permitted, mkdir 'C:\']
});
也可参见 mkdir(2)
。
fs.mkdirSync(path[, options])
#
同步地创建目录。
返回 undefined
,或创建的第一个目录的路径(如果 recursive
为 true
)。
这是 fs.mkdir()
的同步版本。
也可参见 mkdir(2)
。
fs.mkdtemp(prefix[, options], callback)
#
prefix
<string>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
callback
<Function>
创建一个唯一的临时目录。
生成要附加在必需的 prefix
后面的六位随机字符,以创建唯一的临时目录。
由于平台的不一致性,请避免在 prefix
中以 X
字符结尾。
在某些平台上,特别是 BSD,可以返回六个以上的随机字符,并用随机字符替换 prefix
中结尾的 X
字符。
创建的目录路径作为字符串传给回调的第二个参数。
可选的 options
参数可以是指定字符编码的字符串,也可以是具有指定要使用的字符编码的 encoding
属性的对象。
fs.mkdtemp(path.join(os.tmpdir(), '目录-'), (err, directory) => {
if (err) throw err;
console.log(directory);
// 打印: /tmp/目录-itXde2 或 C:\Users\...\AppData\Local\Temp\目录-itXde2
});
fs.mkdtemp()
方法将六位随机选择的字符直接附加到 prefix
字符串。
例如,给定目录 /tmp
,如果打算在 /tmp
中创建临时目录,则 prefix
必须在尾部加上特定平台的路径分隔符(require('path').sep
)。
// 新的临时目录的父目录。
const tmpDir = os.tmpdir();
// 此用法是错误的:
fs.mkdtemp(tmpDir, (err, directory) => {
if (err) throw err;
console.log(directory);
// 输出类似 `/tmpabc123`。
// 新的临时目录会被创建在文件系统根目录,而不是在 /tmp 目录中。
});
// 此用法是正确的:
const { sep } = require('path');
fs.mkdtemp(`${tmpDir}${sep}`, (err, directory) => {
if (err) throw err;
console.log(directory);
// 输出类似 `/tmp/abc123`。
// 新的临时目录会被创建在 /tmp 目录中。
});
fs.mkdtempSync(prefix[, options])
#
返回创建的目录路径。
有关详细信息,请参见此 API 异步版本的文档:fs.mkdtemp()
。
可选的 options
参数可以是指定字符编码的字符串,也可以是具有指定要使用的字符编码的 encoding
属性的对象。
fs.open(path[, flags[, mode]], callback)
#
path
<string> | <Buffer> | <URL>flags
<string> | <number> 参见文件系统flag
的支持。 默认值:'r'
。mode
<string> | <integer> 默认值:0o666
(可读写)。callback
<Function>
异步地打开文件。
参见 open(2)
。
mode
用于设置文件模式(权限和粘滞位),但仅限于创建文件时。
在 Windows 上,只能操作写权限,参见 fs.chmod()
。
回调有两个参数 (err, fd)
。
有些字符 (< > : " / \ | ? *
) 在 Windows 上是预留的,参见命名文件、路径以及命名空间。
在 NTFS 上,如果文件名包含冒号,则 Node.js 会打开文件系统流,参见此 MSDN 页面。
基于 fs.open()
的函数也会表现出以上行为,比如 fs.writeFile()
、 fs.readFile()
等。
fs.opendir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>callback
<Function>
异步地打开目录。
参见 opendir(3)
。
创建一个 fs.Dir
,其中包含所有用于更进一步读取和清理目录的的函数。
encoding
选项用于在打开目录和后续的读取操作时设置 path
的字符编码。
fs.opendirSync(path[, options])
#
同步地打开目录。
参见 opendir(3)
。
创建一个 fs.Dir
,其中包含所有用于更进一步读取和清理目录的函数。
encoding
选项用于在打开目录和后续的读取操作时设置 path
的字符编码。
fs.openSync(path[, flags, mode])
#
path
<string> | <Buffer> | <URL>flags
<string> | <number> 默认值:'r'
。参见文件系统flag
的支持。mode
<string> | <integer> 默认值:0o666
。- 返回: <number>
返回表示文件描述符的整数。
详见此 API 的异步版本的文档:fs.open()
。
fs.read(fd, buffer, offset, length, position, callback)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer>length
<integer>position
<integer>callback
<Function>
从 fd
指定的文件中读取数据。
buffer
是数据(从 fd 读取)要被写入的 buffer。
offset
是 buffer 中开始写入的偏移量。
length
是整数,指定要读取的字节数。
position
参数指定从文件中开始读取的位置。
如果 position
为 null
,则从当前文件位置读取数据,并更新文件位置。
如果 position
是整数,则文件位置会保持不变。
回调有三个参数 (err, bytesRead, buffer)
。
如果文件没有被同时地修改,则当读取的字节数为零时,即到达文件的末尾。
如果调用此方法的 util.promisify()
版本,则返回 Promise
(会传入具有 bytesRead
属性和 buffer
属性的 Object
)。
fs.read(fd, [options,] callback)
#
fd
<integer>options
<Object>buffer
<Buffer> | <TypedArray> | <DataView> Default:Buffer.alloc(16384)
offset
<integer> Default:0
length
<integer> Default:buffer.length
position
<integer> Default:null
callback
<Function>
Similar to the above fs.read
function, this version takes an optional options
object.
If no options
object is specified, it will default with the above values.
fs.readdir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>callback
<Function>err
<Error>files
<string[]> | <Buffer[]> | <fs.Dirent[]>
异步的 readdir(3)
。
读取目录的内容。
回调有两个参数 (err, files)
,其中 files
是目录中文件的名称的数组(不包括 '.'
和 '..'
)。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于传给回调的文件名的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的文件名会作为 Buffer
对象传入。
如果 options.withFileTypes
被设置为 true
,则 files
数组会包含 fs.Dirent
对象。
fs.readdirSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>- 返回: <string[]> | <Buffer[]> | <fs.Dirent[]>
同步的 readdir(3)
。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于返回的文件名的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的文件名会作为 Buffer
对象传入。
如果 options.withFileTypes
被设置为 true
,则结果会包含 fs.Dirent
对象。
fs.readFile(path[, options], callback)
#
path
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。options
<Object> | <string>encoding
<string> | <null> 默认值:null
。flag
<string> 参见文件系统flag
的支持。默认值:'r'
。
callback
<Function>
异步地读取文件的全部内容。
fs.readFile('文件名', (err, data) => {
if (err) throw err;
console.log(data);
});
回调会传入两个参数 (err, data)
,其中 data
是文件的内容。
如果没有指定字符编码,则返回原始的 buffer。
如果 options
是字符串,则它指定字符编码:
fs.readFile('文件名', 'utf8', callback);
当路径是目录时,则 fs.readFile()
和 fs.readFileSync()
的行为是特定于平台的。
在 macOS、Linux 和 Windows 上,会返回错误。
在 FreeBSD 上,会返回目录内容的表示。
// 在 macOS、Linux 和 Windows 上:
fs.readFile('<目录>', (err, data) => {
// => [Error: EISDIR: illegal operation on a directory, read <目录>]
});
// 在 FreeBSD 上:
fs.readFile('<目录>', (err, data) => {
// => null, <data>
});
fs.readFile()
函数会缓冲整个文件。
若要最小化内存成本,则尽可能选择流式(使用 fs.createReadStream()
)。
文件描述符#
- 任何指定的文件描述符都必须支持读取。
- 如果将文件描述符指定为
path
,则不会自动关闭它。 - 读数将从当前位置开始。例如,如果文件已经有内容
'Hello World
' 并且使用文件描述符读取了六个字节,则使用相同文件描述符调用fs.readFile()
将返回'World'
而不是'Hello World'
。
fs.readFileSync(path[, options])
#
path
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。options
<Object> | <string>encoding
<string> | <null> 默认值:null
。flag
<string> 参见文件系统flag
的支持。 默认值:'r'
。
- 返回: <string> | <Buffer>
返回 path
的内容。
详见此 API 的异步版本的文档:fs.readFile()
。
如果指定了 encoding
选项,则此函数返回字符串。
否则,返回 buffer。
与 fs.readFile()
相似,当路径是目录时, fs.readFileSync()
的行为是特定于平台的。
// 在 macOS、Linux 和 Windows 上:
fs.readFileSync('<目录>');
// => [Error: EISDIR: illegal operation on a directory, read <目录>]
// 在 FreeBSD 上:
fs.readFileSync('<目录>'); // => <data>
fs.readlink(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
callback
<Function>
异步的 readlink(2)
。
回调会传入两个参数 (err, linkString)
。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于传给回调的链接路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的链接路径会作为 Buffer
对象传入。
fs.readlinkSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
- 返回: <string> | <Buffer>
同步的 readlink(2)
。
返回符号链接的字符串值。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于返回的链接路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的链接路径会作为 Buffer
对象传入。
fs.readSync(fd, buffer, offset, length, position)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer>length
<integer>position
<integer>- 返回: <number>
返回 bytesRead
的数量。
有关详细信息,请参见此 API 异步版本的文档:fs.read()
。
fs.readSync(fd, buffer, [options])
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>options
<Object>- Returns: <number>
Returns the number of bytesRead
.
Similar to the above fs.readSync
function, this version takes an optional options
object.
If no options
object is specified, it will default with the above values.
For detailed information, see the documentation of the asynchronous version of
this API: fs.read()
.
fs.readv(fd, buffers[, position], callback)
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer>callback
<Function>err
<Error>bytesRead
<integer>buffers
<ArrayBufferView[]>
Read from a file specified by fd
and write to an array of ArrayBufferView
s
using readv()
.
position
is the offset from the beginning of the file from where data
should be read. If typeof position !== 'number'
, the data will be read
from the current position.
The callback will be given three arguments: err
, bytesRead
, and
buffers
. bytesRead
is how many bytes were read from the file.
If this method is invoked as its util.promisify()
ed version, it returns
a Promise
for an Object
with bytesRead
and buffers
properties.
fs.readvSync(fd, buffers[, position])
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer>- Returns: <number> The number of bytes read.
For detailed information, see the documentation of the asynchronous version of
this API: fs.readv()
.
fs.realpath(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
callback
<Function>
通过解析 .
、 ..
和符号链接异步地计算规范路径名。
规范路径名不一定是唯一的。 硬链接和绑定装载可以通过许多路径名暴露文件系统实体。
此函数的行为类似于 realpath(3)
,但有一些例外:
-
在不区分大小写的文件系统上不执行大小写转换。。
-
符号链接的最大数量与平台无关,并且通常高于本地
realpath(3)
实现支持的数量。
callback
有两个参数 (err, resolvedPath)
。
可以使用 process.cwd
来解析相对路径。
仅支持可转换为 UTF8 字符串的路径。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于传给回调的路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的路径会作为 Buffer
对象传入。
如果 path
解析为套接字或管道,则该函数将返回该对象的系统相关名称。
fs.realpath.native(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
callback
<Function>
异步的 realpath(3)
。
callback
有两个参数 (err, resolvedPath)
。
仅支持可转换为 UTF8 字符串的路径。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于传给回调的路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的路径会作为 Buffer
对象传入。
在 Linux 上,当 Node.js 与 musl libc 链接时,procfs 文件系统必须挂载在 /proc
上才能使此功能正常工作。
Glibc 没有这个限制。
fs.realpathSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
- 返回: <string> | <Buffer>
返回已解析的路径名。
详见此 API 的异步版本的文档:fs.realpath()
。
fs.realpathSync.native(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
- Returns: <string> | <Buffer>
同步的 realpath(3)
。
仅支持可转换为 UTF8 字符串的路径。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于返回的路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的路径会作为 Buffer
对象传入。
在 Linux 上,当 Node.js 与 musl libc 链接时,procfs 文件系统必须挂载在 /proc
上才能使此功能正常工作。
Glibc 没有这个限制。
fs.rename(oldPath, newPath, callback)
#
oldPath
<string> | <Buffer> | <URL>newPath
<string> | <Buffer> | <URL>callback
<Function>err
<Error>
异步地把 oldPath
文件重命名为 newPath
提供的路径名。
如果 newPath
已存在,则覆盖它。
除了可能的异常,完成回调没有其他参数。
也可参见 rename(2)
。
fs.rename('旧文件.txt', '新文件.txt', (err) => {
if (err) throw err;
console.log('重命名完成');
});
fs.renameSync(oldPath, newPath)
#
同步的 rename(2)
。返回 undefined
。
fs.rmdir(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,则 Node.js 会重试该操作(每次尝试时使用retryDelay
毫秒时长的线性回退等待)。 此选项表示重试的次数。 如果recursive
选项不为true
,则此选项会被忽略。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归的目录删除。 在递归模式中,错误不会被报告(如果path
不存在),并且操作会被重试(当失败时)。 默认值:false
。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则此选项会被忽略。 默认值:100
。
callback
<Function>err
<Error>
异步的 rmdir(2)
。
除了可能的异常,完成回调没有其他参数。
对文件(而不是目录)使用 fs.rmdir()
会导致 ENOENT
错误(在 Windows 上)或 ENOTDIR
错误(在 POSIX 上)。
fs.rmdirSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,则 Node.js 会重试该操作(每次尝试时使用retryDelay
毫秒时长的线性回退等待)。 此选项表示重试的次数。 如果recursive
选项不为true
,则此选项会被忽略。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归的目录删除。 在递归模式中,错误不会被报告(如果path
不存在),并且操作会被重试(当失败时)。 默认值:false
。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则此选项会被忽略。 默认值:100
。
同步的 rmdir(2)
。
返回 undefined
。
对文件(而不是目录)使用 fs.rmdirSync()
会导致 ENOENT
错误(在 Windows 上)或 ENOTDIR
错误(在 POSIX 上)。
fs.rm(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>force
<boolean> Whentrue
, exceptions will be ignored ifpath
does not exist. Default:false
.maxRetries
<integer> If anEBUSY
,EMFILE
,ENFILE
,ENOTEMPTY
, orEPERM
error is encountered, Node.js will retry the operation with a linear backoff wait ofretryDelay
milliseconds longer on each try. This option represents the number of retries. This option is ignored if therecursive
option is nottrue
. Default:0
.recursive
<boolean> Iftrue
, perform a recursive removal. In recursive mode operations are retried on failure. Default:false
.retryDelay
<integer> The amount of time in milliseconds to wait between retries. This option is ignored if therecursive
option is nottrue
. Default:100
.
callback
<Function>err
<Error>
Asynchronously removes files and directories (modeled on the standard POSIX rm
utility). No arguments other than a possible exception are given to the
completion callback.
fs.rmSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>force
<boolean> Whentrue
, exceptions will be ignored ifpath
does not exist. Default:false
.maxRetries
<integer> If anEBUSY
,EMFILE
,ENFILE
,ENOTEMPTY
, orEPERM
error is encountered, Node.js will retry the operation with a linear backoff wait ofretryDelay
milliseconds longer on each try. This option represents the number of retries. This option is ignored if therecursive
option is nottrue
. Default:0
.recursive
<boolean> Iftrue
, perform a recursive directory removal. In recursive mode operations are retried on failure. Default:false
.retryDelay
<integer> The amount of time in milliseconds to wait between retries. This option is ignored if therecursive
option is nottrue
. Default:100
.
Synchronously removes files and directories (modeled on the standard POSIX rm
utility). Returns undefined
.
fs.stat(path[, options], callback)
#
path
<string> | <Buffer> | <URL>options
<Object>callback
<Function>err
<Error>stats
<fs.Stats>
异步的 stat(2)
。
回调有两个参数 (err, stats)
,其中 stats
是 fs.Stats
对象。
如果发生错误,则 err.code
会是常见的系统错误之一。
不建议在调用 fs.open()
、 fs.readFile()
或 fs.writeFile()
之前使用 fs.stat()
检查文件的存在性。
而是应该直接地打开、读取或写入文件,如果文件不可用,则处理引发的错误。
若要只检查文件是否存在,但没有更多的操作,则建议使用 fs.access()
。
例如,给定以下的目录结构:
- 目录
-- 文件.txt
- 文件.js
以下程序会检查给定路径的文件属性:
const fs = require('fs');
const pathsToCheck = ['./目录', './目录/文件.txt'];
for (let i = 0; i < pathsToCheck.length; i++) {
fs.stat(pathsToCheck[i], function(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.statSync(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>- 返回: <fs.Stats>
同步的 stat(2)
。
fs.symlink(target, path[, type], callback)
#
target
<string> | <Buffer> | <URL>path
<string> | <Buffer> | <URL>type
<string>callback
<Function>err
<Error>
异步的 symlink(2)
,它会创建名为 path
的链接,该链接指向 target
。
除了可能的异常,完成回调没有其他参数。
type
参数仅在 Windows 上可用,在其他平台上则会被忽略。
它可以被设置为 'dir'
、 'file'
或 'junction'
。
如果未设置 type
参数,则 Node.js 将会自动检测 target
的类型并使用 'file'
或 'dir'
。
如果 target
不存在,则将会使用 'file'
。
Windows 上的连接点要求目标路径是绝对路径。
当使用 'junction'
时, target
参数将会自动地标准化为绝对路径。
相对目标是相对于链接的父目录。
fs.symlink('./mew', './example/mewtwo', callback);
上面的示例中,在 example
中创建了符号链接 mewtwo
,它指向同一目录中的 mew
:
$ tree example/
example/
├── mew
└── mewtwo -> ./mew
fs.symlinkSync(target, path[, type])
#
返回 undefined
。
详见此 API 的异步版本的文档:fs.symlink()
。
fs.truncate(path[, len], callback)
#
异步的 truncate(2)
。
除了可能的异常,完成回调没有其他参数。
文件描述符也可以作为第一个参数传入。
在这种情况下,调用 fs.ftruncate()
。
不推荐传入文件描述符,可能导致将来抛出错误。
fs.truncateSync(path[, len])
#
同步的 truncate(2)
。
返回 undefined
。
文件描述符也可以作为第一个参数传入。
在这种情况下,调用 fs.ftruncateSync()
。
不推荐传入文件描述符,可能导致将来抛出错误。
fs.unlink(path, callback)
#
path
<string> | <Buffer> | <URL>callback
<Function>err
<Error>
异步地删除文件或符号链接。 除了可能的异常,完成回调没有其他参数。
// 假设 '文件.txt' 是普通的文件。
fs.unlink('文件.txt', (err) => {
if (err) throw err;
console.log('文件已被删除');
});
fs.unlink()
对空或非空的目录均不起作用。
若要删除目录,则使用 fs.rmdir()
。
也可参见 unlink(2)
。
fs.unlinkSync(path)
#
同步的 unlink(2)
。
返回 undefined
。
fs.unwatchFile(filename[, listener])
#
filename
<string> | <Buffer> | <URL>listener
<Function> 可选的,之前使用fs.watchFile()
绑定的监听器。
停止监视 filename
的变化。
如果指定了 listener
,则仅移除此特定监听器,否则,将移除所有监听器,从而停止监视 filename
。
对未被监视的文件名调用 fs.unwatchFile()
将是空操作,而不是错误。
使用 fs.watch()
比 fs.watchFile()
和 fs.unwatchFile()
更高效。
应尽可能使用 fs.watch()
代替 fs.watchFile()
和 fs.unwatchFile()
。
fs.utimes(path, atime, mtime, callback)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>callback
<Function>err
<Error>
更改 path
指向的对象的文件系统时间戳。
atime
和 mtime
参数遵循以下规则:
- 值可以是表示 Unix 纪元时间(以秒为单位)的数字、
Date
对象、或类似'123456789.0'
的数值字符串。 - 如果该值无法转换为数值、或值为
NaN
、Infinity
或-Infinity
,则抛出错误。
fs.utimesSync(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>
返回 undefined
。
详见此 API 的异步版本的文档:fs.utimes()
。
fs.watch(filename[, options][, listener])
#
filename
<string> | <Buffer> | <URL>options
<string> | <Object>listener
<Function> | <undefined> 默认值:undefined
。- 返回: <fs.FSWatcher>
监视 filename
的更改,其中 filename
是文件或目录。
第二个参数是可选的。
如果 options
传入字符串,则它指定 encoding
。
否则, options
应传入对象。
监听器回调有两个参数 (eventType, filename)
。
eventType
是 'rename'
或 'change'
, filename
是触发事件的文件的名称。
在大多数平台上,每当文件名在目录中出现或消失时,就会触发 'rename'
事件。
监听器回调绑定在由 fs.FSWatcher
触发的 'change'
事件上,但它与 eventType
的 'change'
值不是一回事。
注意事项#
fs.watch
的 API 在各个平台上并非 100% 一致,在某些情况下不可用。
仅在 macOS 和 Windows 上支持 recursive
选项。
当在不支持该选项的平台上使用该选项时,则会抛出 ERR_FEATURE_UNAVAILABLE_ON_PLATFORM
异常。
在 Windows 上,如果监视的目录被移动或重命名,则不会触发任何事件。
当监视的目录被删除时,则报告 EPERM
错误。
可用性#
此特性取决于底层操作系统,提供了一种通知文件系统更改的方法。
- 在 Linux 系统上,使用
inotify(7)
。 - 在 BSD 系统上,使用
kqueue(2)
。 - 在 macOS 系统上,对文件使用
kqueue(2)
,对目录使用FSEvents
。 - 在 SunOS 系统上(包括 Solaris 和 SmartOS),使用事件端口。
- 在 Windows 系统上,此特性取决于
ReadDirectoryChangesW
。 - 在 Aix 系统上,此特性取决于
AHAFS
必须启动。 - 在 IBM i 系统上,不支持此特性。
如果底层功能由于某些原因不可用,则 fs.watch()
会无法运行且可能抛出异常。
例如,当使用虚拟化软件(如 Vagrant 或 Docker)时,在网络文件系统(NFS、SMB 等)或主文件系统上监视文件或目录可能是不可靠的,在某些情况下也是不可能的。
仍然可以使用 fs.watchFile()
,因为它使用 stat 轮询 ,但这种方法较慢且不太可靠。
索引节点#
在 Linux 或 macOS 系统上, fs.watch()
解析路径到索引节点并监视该索引节点。
如果删除并重新创建监视的路径,则会为其分配一个新的索引节点。
监视器会因删除而触发事件,但会继续监视原始的索引节点。
不会因新建索引节点而触发事件。
这是预期的行为。
AIX 文件在文件的生命周期中保留相同的索引节点。 在 AIX 上保存和关闭监视的文件将导致两个通知(一个用于添加新内容,一个用于截断)。
文件名参数#
仅在 Linux、macOS、Windows 和 AIX 上支持在回调中提供 filename
参数。
即使在支持的平台上,也不总是保证提供 filename
。
因此,不要假设在回调中始终提供 filename
参数,并且如果它为 null
则需要一些后备逻辑。
fs.watch('somedir', (eventType, filename) => {
console.log(`事件类型是: ${eventType}`);
if (filename) {
console.log(`提供的文件名: ${filename}`);
} else {
console.log('文件名未提供');
}
});
fs.watchFile(filename[, options], listener)
#
filename
<string> | <Buffer> | <URL>options
<Object>listener
<Function>current
<fs.Stats>previous
<fs.Stats>
- Returns: <fs.StatWatcher>
监视 filename
的更改。
每当访问文件时都会调用 listener
回调。
options
参数可以省略。
如果提供,则它应该是一个对象。
options
对象可以包含一个名为 persistent
的布尔值,指示当文件正在被监视时,进程是否应该继续运行。
options
对象可以指定 interval
属性,指示轮询目标的频率(以毫秒为单位)。
listener
有两个参数,当前的 stat 对象和之前的 stat 对象:
fs.watchFile('message.text', (curr, prev) => {
console.log(`当前的最近修改时间是: ${curr.mtime}`);
console.log(`之前的最近修改时间是: ${prev.mtime}`);
});
这些 stat 对象是 fs.Stat
的实例。
如果 bigint
选项为 true
,则这些对象中的数值会被指定为 BigInts
类型。
要在修改文件(而不仅仅是访问)时收到通知,则需要比较 curr.mtime
和 prev.mtime
。
当 fs.watchFile
操作导致 ENOENT
错误时,它将调用一次监听器,并将所有字段置零(或将日期设为 Unix 纪元)。
如果文件是在那之后创建的,则监听器会被再次调用,且带上最新的 stat 对象。
这是 v0.10 之后的功能变化。
使用 fs.watch()
比 fs.watchFile
和 fs.unwatchFile
更高效。
应尽可能使用 fs.watch
代替 fs.watchFile
和 fs.unwatchFile
。
当 fs.watchFile()
正在监视的文件消失并重新出现时,第二次回调事件(文件重新出现)中的 previous
的内容会与第一次回调事件(文件消失)中的 previous
的内容相同。
这种情况发生在:
- 文件被删除,然后又恢复。
- 文件被重命名,然后再第二次重命名回其原来的名称。
fs.write(fd, buffer[, offset[, length[, position]]], callback)
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView>offset
<integer>length
<integer>position
<integer>callback
<Function>err
<Error>bytesWritten
<integer>buffer
<Buffer> | <TypedArray> | <DataView>
写入 buffer
到 fd
指定的文件。
offset
决定 buffer 中要被写入的部位, length
是整数,指定要写入的字节数。
position
指定文件开头的偏移量(数据要被写入的位置)。
如果 typeof position !== 'number'
,则数据会被写入当前的位置。
参见 pwrite(2)
。
回调有三个参数 (err, bytesWritten, buffer)
,其中 bytesWritten
指定从 buffer
中被写入的字节数。
如果调用此方法的 util.promisify()
版本,则返回 Promise
(会传入具有 bytesWritten
和 buffer
属性的 Object
)。
不等待回调就对同一个文件多次使用 fs.write()
是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
fs.write(fd, string[, position[, encoding]], callback)
#
fd
<integer>string
<string> | <Object>position
<integer>encoding
<string> 默认值:'utf8'
。callback
<Function>
将 string
写入到 fd
指定的文件。
如果 string
不是字符串或具有自有 toString
函数属性的对象,则抛出异常。
position
指定文件开头的偏移量(数据要被写入的位置)。
如果 typeof position !== 'number'
,则数据会被写入当前的位置。
参见 pwrite(2)
。
encoding
是期望的字符串编码。
回调会接收到参数 (err, written, string)
,其中 written
指定传入的字符串中被要求写入的字节数。
被写入的字节数不一定与被写入的字符串字符数相同。
参见 Buffer.byteLength
。
不等待回调就对同一个文件多次使用 fs.write()
是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
在 Windows 上,如果文件描述符连接到控制台(例如 fd == 1
或 stdout
),则无论使用何种编码,包含非 ASCII 字符的字符串默认情况下都不会被正确地渲染。
通过使用 chcp 65001
命令更改活动的代码页,可以将控制台配置为正确地渲染 UTF-8。
详见 chcp 文档。
fs.writeFile(file, data[, options], callback)
#
file
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。data
<string> | <Buffer> | <TypedArray> | <DataView>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
。mode
<integer> 默认值:0o666
。flag
<string> 参见文件系统flag
的支持。 默认值:'w'
。
callback
<Function>err
<Error>
当 file
是文件名时,则异步地写入数据到文件(如果文件已存在,则覆盖文件)。
data
可以是字符串或 buffer。
当 file
是文件描述符时,则其行为类似于直接调用 fs.write()
(建议使用)。
参见以下关于使用文件描述符的说明。
如果 data
是 buffer,则 encoding
选项会被忽略。
如果 data
是普通的对象,则它必须具有自身的 toString
函数属性。
const data = new Uint8Array(Buffer.from('Node.js 中文网'));
fs.writeFile('文件.txt', data, (err) => {
if (err) throw err;
console.log('文件已保存');
});
如果 options
是字符串,则它指定字符编码:
fs.writeFile('文件.txt', 'Node.js 中文网', 'utf8', callback);
不等待回调就对同一个文件多次使用 fs.writeFile()
是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
使用 fs.writeFile() 与文件描述符#
当 file
是一个文件描述符时,行为几乎与直接调用 fs.write()
类似:
fs.write(fd, Buffer.from(data, options.encoding), callback);
与直接调用 fs.write()
的区别在于,在某些异常情况下, fs.write()
可能只写入部分 buffer,需要重试以写入剩余的数据,而 fs.writeFile()
将会重试直到数据完全写入(或发生错误)。
这种影响是混淆的常见原因。 在文件描述符的情况下,文件不会被替换! 数据不一定写入到文件的开头,文件的原始数据可以保留在新写入的数据之前和/或之后。
例如,如果连续两次调用 fs.writeFile()
,首先写入字符串 'Hello'
,然后写入字符串 ', World'
,则该文件将会包含 'Hello, World'
,并且可能包含文件的一些原始数据(取决于原始文件的大小和文件描述符的位置)。
如果使用了文件名而不是描述符,则该文件将会保证仅包含 ', World'
。
fs.writeFileSync(file, data[, options])
#
file
<string> | <Buffer> | <URL> | <integer> 文件名或文件描述符。data
<string> | <Buffer> | <TypedArray> | <DataView>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
。mode
<integer> 默认值:0o666
。flag
<string> 参见文件系统flag
的支持。 默认值:'w'
。
返回 undefined
。
详见此 API 的异步版本的文档:fs.writeFile()
。
fs.writeSync(fd, buffer[, offset[, length[, position]]])
#
fd
<integer>buffer
<Buffer> | <TypedArray> | <DataView> | <string> | <Object>offset
<integer>length
<integer>position
<integer>- 返回: <number> 写入的字节数。
详见此 API 的异步版本的文档:fs.write(fd, buffer...)
。
fs.writeSync(fd, string[, position[, encoding]])
#
详见此 API 的异步版本的文档: fs.write(fd, string...)
。
fs.writev(fd, buffers[, position], callback)
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer>callback
<Function>err
<Error>bytesWritten
<integer>buffers
<ArrayBufferView[]>
使用 writev()
将一个 ArrayBufferView
数组写入 fd
指定的文件。
position
指定文件开头的偏移量(数据要被写入的位置)。
如果 typeof position !== 'number'
,则数据会被写入当前的位置。
回调有三个参数:err
、 bytesWritten
和 buffers
。
bytesWritten
是从 buffers
写入的字节数。
如果此方法是 util.promisify()
化的版本,则它返回的 Promise
会返回具有 bytesWritten
和 buffers
属性的 Object
。
不等待回调就对同一个文件多次使用 fs.writev()
是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
fs.writevSync(fd, buffers[, position])
#
fd
<integer>buffers
<ArrayBufferView[]>position
<integer>- 返回: <number> 写入的字节数。
详见此 API 的异步版本的文档:fs.writev()
。
fs 的 Promise API#
fs.promises
API 提供了一组备用的异步文件系统的方法,它们返回 Promise
对象而不是使用回调。
API 可通过 require('fs').promises
或 require('fs/promises')
访问。
FileHandle 类#
FileHandle
对象是数字文件描述符的包装器。
FileHandle
的实例与数字文件描述符的不同之处在于它们提供了一个面向对象的 API 来处理文件。
如果没有使用 filehandle.close()
方法关闭 FileHandle
,则它可能会自动关闭文件描述符并触发进程警告,从而有助于防止内存泄漏。
请不要在代码中依赖此行为,因为它不可靠,且该文件可能无法关闭。
相反,应该始终显式的关闭 FileHandles
。
Node.js 将来可能会改变这种行为。
FileHandle
对象的实例由 fsPromises.open()
方法在内部创建。
与基于回调的 API(如 fs.fstat()
、 fs.fchown()
、 fs.fchmod()
等)不同,基于 promise 的 API 不使用数字文件描述符。
而是,基于 promise 的 API 使用 FileHandle
类,以帮助避免在解决或拒绝 Promise
后意外泄漏未关闭的文件描述符。
filehandle.appendFile(data, options)
#
当在文件句柄上进行操作时,无法将模式更改为使用 fsPromises.open()
设置的模式。
因此,这等效于 filehandle.writeFile()
。
filehandle.chmod(mode)
#
更改文件的权限。
Promise
将会在成功时解决,且不带参数。
filehandle.chown(uid, gid)
#
更改文件的所有者,然后在成功时解决 Promise
且不带参数。
filehandle.close()
#
- 返回: <Promise> 如果底层的文件描述符被关闭则
Promise
将会被解决,如果关闭时发生错误则将Promise
将会被拒绝。
等待句柄上的所有处理中的操作完成之后,关闭文件句柄。
const fsPromises = require('fs').promises;
async function openAndClose() {
let filehandle;
try {
filehandle = await fsPromises.open('thefile.txt', 'r');
} finally {
if (filehandle !== undefined)
await filehandle.close();
}
}
filehandle.datasync()
#
- 返回: <Promise>
异步的 fdatasync(2)
。
Promise
将会在成功时解决,且不带参数。
filehandle.fd
#
- <number> 由
FileHandle
对象管理的数字文件描述符。
filehandle.read(buffer, offset, length, position)
#
从文件中读取数据。
buffer
是数据将写入的缓冲区。
offset
是 buffer 中开始写入的偏移量。
length
是整数,指定要读取的字节数。
position
参数指定从文件中开始读取的位置。
如果 position
为 null
,则从当前文件位置读取数据,并更新文件位置。
如果 position
是整数,则文件位置会保持不变。
成功读取之后, Promise
会被解决并带上一个对象,对象上有一个 bytesRead
属性(指定读取的字节数)和一个 buffer
属性(指向传入的 buffer
参数)。
如果文件没有被同时地修改,则当读取的字节数为零时,即到达文件的末尾。
filehandle.read(options)
#
options
<Object>buffer
<Buffer> | <Uint8Array> Default:Buffer.alloc(16384)
offset
<integer> Default:0
length
<integer> Default:buffer.length
position
<integer> Default:null
- Returns: <Promise>
filehandle.readFile(options)
#
异步地读取文件的全部内容。
Promise
被解决时会带上文件的内容。
如果没有指定字符编码(使用 options.encoding
),则数据会以 Buffer
对象返回。
否则,数据将会是一个字符串。
如果 options
是字符串,则它指定字符编码。
FileHandle
必须支持读取。
如果对文件句柄进行了一次或多次 filehandle.read()
调用,然后再调用 filehandle.readFile()
,则将从当前位置读取数据,直到文件结束。
它并不总是从文件的开头读取。
filehandle.readv(buffers[, position])
#
buffers
<ArrayBufferView[]>position
<integer>- Returns: <Promise>
Read from a file and write to an array of ArrayBufferView
s
The Promise
is resolved with an object containing a bytesRead
property
identifying the number of bytes read, and a buffers
property containing
a reference to the buffers
input.
position
is the offset from the beginning of the file where this data
should be read from. If typeof position !== 'number'
, the data will be read
from the current position.
filehandle.stat([options])
#
检索文件的 fs.Stats
。
filehandle.sync()
#
- 返回: <Promise>
异步的 fsync(2)
。
Promise
将会在成功时解决,且不带参数。
filehandle.truncate(len)
#
截断文件,然后在成功时解决 Promise
且不带参数。
如果文件大于 len
个字节,则只有前面 len
个字节会保留在文件中。
例如,以下程序只保留文件的前 4 个字节:
const fs = require('fs');
const fsPromises = fs.promises;
console.log(fs.readFileSync('temp.txt', 'utf8'));
// 打印: Node.js
async function doTruncate() {
let filehandle = null;
try {
filehandle = await fsPromises.open('temp.txt', 'r+');
await filehandle.truncate(4);
} finally {
if (filehandle) {
// 如果文件已打开,则关闭文件。
await filehandle.close();
}
}
console.log(fs.readFileSync('temp.txt', 'utf8')); // 打印: Node
}
doTruncate().catch(console.error);
如果文件小于 len
个字节,则会对其进行扩展,并且扩展部分将填充空字节('\0'
):
const fs = require('fs');
const fsPromises = fs.promises;
console.log(fs.readFileSync('temp.txt', 'utf8'));
// 打印: Node.js
async function doTruncate() {
let filehandle = null;
try {
filehandle = await fsPromises.open('temp.txt', 'r+');
await filehandle.truncate(10);
} finally {
if (filehandle) {
// 如果文件已打开,则关闭文件。
await filehandle.close();
}
}
console.log(fs.readFileSync('temp.txt', 'utf8')); // 打印 Node.js\0\0\0
}
doTruncate().catch(console.error);
最后 3 个字节是空字节('\0'
),以补充超出的截断。
filehandle.utimes(atime, mtime)
#
更改 FileHandle
指向的对象的文件系统时间戳,然后在成功时解决 Promise
且不带参数。
此函数在 7.1 之前的 AIX 版本上不起作用,它将会解决 Promise
并带上使用 UV_ENOSYS
代码的错误。
filehandle.write(buffer[, offset[, length[, position]]])
#
buffer
<Buffer> | <Uint8Array> | <string> | <Object>offset
<integer>length
<integer>position
<integer>- 返回: <Promise>
写入 buffer
到文件。
Promise
会被解决并带上一个对象,对象包含一个 bytesWritten
属性(指定写入的字节数)和一个 buffer
属性(指向写入的 buffer
)。
offset
决定 buffer 中要被写入的部位, length
是整数,指定要写入的字节数。
position
指定文件开头的偏移量(数据要被写入的位置)。
如果 typeof position !== 'number'
,则数据会被写入当前的位置。
参见 pwrite(2)
。
在同一个文件上多次使用 filehandle.write()
且不等待 Promise
被解决(或被拒绝)是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
filehandle.write(string[, position[, encoding]])
#
将 string
写入到文件。
如果 string
不是字符串或具有自有 toString
函数属性的对象,则抛出异常。
Promise
会被解决并带上一个对象,对象包含一个 bytesWritten
属性(指定写入的字节数)和一个 buffer
属性(指向写入的 string
)。
position
指定文件开头的偏移量(数据要被写入的位置)。
如果 position
的类型不是一个 number
,则数据会被写入当前的位置。
参见 pwrite(2)
。
encoding
是期望的字符串编码。
在同一个文件上多次使用 filehandle.write()
且不等待 Promise
被解决(或被拒绝)是不安全的。
对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
filehandle.writeFile(data, options)
#
异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。
data
可以是字符串、buffer、或具有自有 toString
函数属性的对象。
Promise
会在成功时被解决,且不带参数。
如果 data
是 buffer,则 encoding
选项会被忽略。
如果 options
是字符串,则它指定字符编码。
FileHandle
必须支持写入。
在同一个文件上多次使用 filehandle.writeFile()
且不等待 Promise
被解决(或被拒绝)是不安全的。
如果对文件句柄进行了一次或多次 filehandle.write()
调用,然后再调用 filehandle.writeFile()
,则将从当前位置写入数据,直到文件结束。
它并不总是从文件的开头写入。
filehandle.writev(buffers[, position])
#
buffers
<ArrayBufferView[]>position
<integer>- 返回: <Promise>
将 ArrayBufferViews
数组写入该文件。
Promise
会被解决并带上一个对象,对象包含一个 bytesWritten
属性(表明写入的字节数)和一个 buffers
属性(指向 buffers
输入)。
position
指定文件开头的偏移量(数据要被写入的位置)。
如果 typeof position !== 'number'
,则数据会被写入当前的位置。
在同一文件上多次调用 writev()
且不等待前面的操作完成,这是不安全的。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
fsPromises.access(path[, mode])
#
测试用户对 path
指定的文件或目录的权限。
mode
参数是一个可选的整数,指定要执行的可访问性检查。
查看文件可访问性的常量了解 mode
的可选值。
可以创建由两个或更多个值按位或组成的掩码(例如 fs.constants.W_OK | fs.constants.R_OK
)。
如果可访问性检查成功,则 Promise
会被解决且不带值。
如果任何可访问性检查失败,则 Promise
会被拒绝并带上 Error
对象。
以下示例会检查当前进程是否可以读取和写入 /etc/passwd
文件。
const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK)
.then(() => console.log('可以访问'))
.catch(() => console.error('不可访问'));
不建议在调用 fsPromises.open()
之前使用 fsPromises.access()
检查文件的可访问性。
这样做会引入竞态条件,因为其他进程可能会在两个调用之间更改文件的状态。
而是,应该直接打开、读取或写入文件,并且当文件无法访问时处理引发的错误。
fsPromises.appendFile(path, data[, options])
#
path
<string> | <Buffer> | <URL> | <FileHandle> 文件名或FileHandle
。data
<string> | <Buffer>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
。mode
<integer> 默认值:0o666
。flag
<string> 参见文件系统flag
的支持。默认值:'a'
。
- 返回: <Promise>
异步地追加数据到文件,如果文件尚不存在则创建文件。
data
可以是字符串或 Buffer
。
Promise
将会在成功时解决,且不带参数。
如果 options
是字符串,则它指定字符编码。
path
可以指定为已打开用于追加(使用 fsPromises.open()
)的 FileHandle
。
fsPromises.chmod(path, mode)
#
更改文件的权限,然后在成功时解决 Promise
且不带参数。
fsPromises.chown(path, uid, gid)
#
更改文件的所有者,然后在成功时解决 Promise
且不带参数。
fsPromises.copyFile(src, dest[, mode])
#
src
<string> | <Buffer> | <URL> 要拷贝的源文件名。dest
<string> | <Buffer> | <URL> 拷贝操作的目标文件名。mode
<integer> 用于拷贝操作的修饰符。默认值:0
。- 返回: <Promise>
异步地将 src
拷贝到 dest
。
默认情况下,如果 dest
已经存在,则覆盖它。
Promise
将会在成功时解决,且不带参数。
Node.js 不保证拷贝操作的原子性。 如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
mode
是一个可选的整数,指定拷贝操作的行为。
可以创建由两个或更多个值按位或组成的掩码(比如 fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE
)。
fs.constants.COPYFILE_EXCL
- 如果dest
已存在,则拷贝操作将失败。fs.constants.COPYFILE_FICLONE
- 拷贝操作将尝试创建写时拷贝(copy-on-write)链接。如果平台不支持写时拷贝,则使用后备的拷贝机制。fs.constants.COPYFILE_FICLONE_FORCE
- 拷贝操作将尝试创建写时拷贝链接。如果平台不支持写时拷贝,则拷贝操作将失败。
const {
promises: fsPromises,
constants: {
COPYFILE_EXCL
}
} = require('fs');
// 默认情况下将创建或覆盖目标文件。
fsPromises.copyFile('源文件.txt', '目标文件.txt')
.then(() => console.log('源文件已拷贝到目标文件'))
.catch(() => console.log('该文件无法拷贝'));
// 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
fsPromises.copyFile('源文件.txt', '目标文件.txt', COPYFILE_EXCL)
.then(() => console.log('源文件已拷贝到目标文件'))
.catch(() => console.log('该文件无法拷贝'));
fsPromises.lchmod(path, mode)
#
更改符号链接的权限,然后在成功时解决 Promise
且不带参数。
此方法仅在 macOS 上实现。
fsPromises.lchown(path, uid, gid)
#
更改符号链接的拥有者,然后在成功时解决 Promise
且不带参数。
fsPromises.lutimes(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>- Returns: <Promise>
Changes the access and modification times of a file in the same way as
fsPromises.utimes()
, with the difference that if the path refers to a
symbolic link, then the link is not dereferenced: instead, the timestamps of
the symbolic link itself are changed.
Upon success, the Promise
is resolved without arguments.
fsPromises.link(existingPath, newPath)
#
异步的 link(2)
。
Promise
将会在成功时解决,且不带参数。
fsPromises.lstat(path[, options])
#
异步的 lstat(2)
。
Promise
会被解决并带上用于给定的符号链接 path
的 fs.Stats
对象。
fsPromises.mkdir(path[, options])
#
异步地创建目录,然后在成功时解决 Promise
,且不带参数,或者带上创建的第一个目录的路径(如果 recursive
为 true
)。
可选的 options
参数可以是整数(指定 mode
(权限和粘滞位))、或对象(具有 mode
属性和 recursive
属性(指示是否要创建父目录))。
当 path
是已存在的目录时,调用 fsPromises.mkdir()
仅在 recursive
为 false 时才导致拒绝。
fsPromises.mkdtemp(prefix[, options])
#
创建一个唯一的临时目录,且解决 Promise
时带上创建的目录路径。
唯一的目录名称是通过在提供的 prefix
的末尾附加六个随机字符来生成的。
由于平台的不一致性,请避免在 prefix
中以 X
字符结尾。
在某些平台上,特别是 BSD,可以返回六个以上的随机字符,并用随机字符替换 prefix
中结尾的 X
字符。
可选的 options
参数可以是指定字符编码的字符串,也可以是具有指定要使用的字符编码的 encoding
属性的对象。
fsPromises.mkdtemp(path.join(os.tmpdir(), 'foo-'))
.catch(console.error);
fsPromises.mkdtemp()
方法将六位随机选择的字符直接附加到 prefix
字符串。
例如,给定目录 /tmp
,如果打算在 /tmp
中创建临时目录,则 prefix
必须在尾部加上特定平台的路径分隔符(require('path').sep
)。
fsPromises.open(path, flags[, mode])
#
path
<string> | <Buffer> | <URL>flags
<string> | <number> 参见文件系统flag
的支持。默认值:'r'
。mode
<string> | <integer> 默认值:0o666
(可读写)。- 返回: <Promise>
异步地打开文件并返回一个 Promise
,当解决时会带上一个 FileHandle
对象。
参见 open(2)
。
mode
用于设置文件模式(权限和粘滞位),但仅限于创建文件时。
有些字符 (< > : " / \ | ? *
) 在 Windows 上是预留的,参见命名文件、路径以及命名空间。
在 NTFS 上,如果文件名包含冒号,则 Node.js 会打开文件系统流,参见此 MSDN 页面。
fsPromises.opendir(path[, options])
#
异步地打开目录。
参见 opendir(3)
。
创建一个 fs.Dir
,其中包含所有用于更进一步读取和清理目录的函数。
encoding
选项用于在打开目录和后续的读取操作时设置 path
的字符编码。
使用异步迭代的示例:
const fs = require('fs');
async function print(path) {
const dir = await fs.promises.opendir(path);
for await (const dirent of dir) {
console.log(dirent.name);
}
}
print('./').catch(console.error);
fsPromises.readdir(path[, options])
#
读取目录的内容,然后解决 Promise
并带上一个数组(包含目录中的文件的名称,但不包括 '.'
和 '..'
)。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于文件名的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的文件名会作为 Buffer
对象传入。
如果 options.withFileTypes
被设置为 true
,则解决的数组会包含 fs.Dirent
对象。
const fs = require('fs');
async function print(path) {
const files = await fs.promises.readdir(path);
for (const file of files) {
console.log(file);
}
}
print('./').catch(console.error);
fsPromises.readFile(path[, options])
#
path
<string> | <Buffer> | <URL> | <FileHandle> 文件名或FileHandle
。options
<Object> | <string>encoding
<string> | <null> 默认值:null
。flag
<string> 参见文件系统flag
的支持。默认值:'r'
。
- 返回: <Promise>
异步地读取文件的全部内容。
Promise
被解决时会带上文件的内容。
如果没有指定字符编码(使用 options.encoding
),则数据会以 Buffer
对象返回。
否则,数据将会是一个字符串。
如果 options
是字符串,则它指定字符编码。
当 path
是目录时, fsPromises.readFile()
的行为是特定于平台的。
在 macOS、Linux 和 Windows 上,promise 将会被拒绝并带上一个错误。
在 FreeBSD 上,则将会返回目录内容的表示。
指定的 FileHandle
必须支持读取。
fsPromises.readlink(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
- 返回: <Promise>
异步的 readlink(2)
。
Promise
会在成功时解决,且带上 linkString
。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于链接路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的链接路径会作为 Buffer
对象传入。
fsPromises.realpath(path[, options])
#
path
<string> | <Buffer> | <URL>options
<string> | <Object>encoding
<string> 默认值:'utf8'
。
- 返回: <Promise>
使用与 fs.realpath.native()
函数相同的语义来判断 path
的实际位置,然后解决 Promise
并带上解析后的路径。
仅支持可转换为 UTF8 字符串的路径。
可选的 options
参数可以是字符串(指定字符编码)、或具有 encoding
属性(指定用于路径的字符编码)的对象。
如果 encoding
被设置为 'buffer'
,则返回的路径会作为 Buffer
对象传入。
在 Linux 上,当 Node.js 与 musl libc 链接时,procfs 文件系统必须挂载在 /proc
上才能使此功能正常工作。
Glibc 没有这个限制。
fsPromises.rename(oldPath, newPath)
#
将 oldPath
重命名为 newPath
,然后在成功时解决 Promise
且不带参数。
fsPromises.rmdir(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>maxRetries
<integer> 如果遇到EBUSY
、EMFILE
、ENFILE
、ENOTEMPTY
或EPERM
错误,则 Node.js 会重试该操作(每次尝试时使用retryDelay
毫秒时长的线性回退等待)。 此选项表示重试的次数。 如果recursive
选项不为true
,则此选项会被忽略。 默认值:0
。recursive
<boolean> 如果为true
,则执行递归的目录删除。 在递归模式中,错误不会被报告(如果path
不存在),并且操作会被重试(当失败时)。 默认值:false
。retryDelay
<integer> 重试之间等待的时间(以毫秒为单位)。 如果recursive
选项不为true
,则此选项会被忽略。 默认值:100
。
- 返回: <Promise>
删除 path
指定的目录,然后在成功时解决 Promise
且不带参数。
对文件(而不是目录)使用 fsPromises.rmdir()
会导致 Promise
被拒绝,在 Windows 上会带上 ENOENT
错误、在 POSIX 上会带上 ENOTDIR
错误。
Setting recursive
to true
results in behavior similar to the Unix command
rm -rf
: an error will not be raised for paths that do not exist, and paths
that represent files will be deleted. The permissive behavior of the
recursive
option is deprecated, ENOTDIR
and ENOENT
will be thrown in
the future.
fsPromises.rm(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>force
<boolean> Whentrue
, exceptions will be ignored ifpath
does not exist. Default:false
.maxRetries
<integer> If anEBUSY
,EMFILE
,ENFILE
,ENOTEMPTY
, orEPERM
error is encountered, Node.js will retry the operation with a linear backoff wait ofretryDelay
milliseconds longer on each try. This option represents the number of retries. This option is ignored if therecursive
option is nottrue
. Default:0
.recursive
<boolean> Iftrue
, perform a recursive directory removal. In recursive mode operations are retried on failure. Default:false
.retryDelay
<integer> The amount of time in milliseconds to wait between retries. This option is ignored if therecursive
option is nottrue
. Default:100
.
Removes files and directories (modeled on the standard POSIX rm
utility).
Resolves the Promise
with no arguments on success.
fsPromises.stat(path[, options])
#
Promise
会被解决并带上 fs.Stats
对象(用于给定的 path
)。
fsPromises.symlink(target, path[, type])
#
target
<string> | <Buffer> | <URL>path
<string> | <Buffer> | <URL>type
<string> 默认值:'file'
。- 返回: <Promise>
创建一个符号链接,然后在成功时解决 Promise
且不带参数。
type
参数仅在 Windows 上可用,可以是 'dir'
、 'file'
或 'junction'
之一。
Windows 上使用 'junction'
要求目标路径是绝对路径。
当使用 'junction'
时, target
参数将自动标准化为绝对路径。
fsPromises.truncate(path[, len])
#
截断 path
,然后在成功时解决 Promise
且不带参数。
path
必须是一个字符串或 Buffer
。
fsPromises.unlink(path)
#
异步的 unlink(2)
。
Promise
将会在成功时解决,且不带参数。
fsPromises.utimes(path, atime, mtime)
#
path
<string> | <Buffer> | <URL>atime
<number> | <string> | <Date>mtime
<number> | <string> | <Date>- 返回: <Promise>
更改 path
指向的对象的文件系统时间戳,然后在成功时解决 Promise
且不带参数。
atime
和 mtime
参数遵循以下规则:
- 值可以是表示 Unix 纪元时间的数字、
Date
对象、或类似'123456789.0'
的数值字符串。 - 如果该值无法转换为数值、或值为
NaN
、Infinity
或-Infinity
,则抛出Error
。
fsPromises.writeFile(file, data[, options])
#
file
<string> | <Buffer> | <URL> | <FileHandle> 文件名或FileHandle
。data
<string> | <Buffer> | <Uint8Array> | <Object>options
<Object> | <string>encoding
<string> | <null> 默认值:'utf8'
。mode
<integer> 默认值:0o666
。flag
<string> 参见文件系统flag
的支持。默认值:'w'
。
- 返回: <Promise>
异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。
data
可以是字符串、buffer、或具有自有 toString
函数属性的对象。
Promise
会在成功时被解决,且不带参数。
如果 data
是 buffer,则 encoding
选项会被忽略。
如果 options
是字符串,则它指定字符编码。
指定的 FileHandle
必须支持写入。
在同一个文件上多次使用 fsPromises.writeFile()
且不等待 Promise
被解决(或被拒绝)是不安全的。
FS 常量#
以下常量由 fs.constants
输出。
并非所有操作系统都可以使用每个常量。
To use more than one constant, use the bitwise OR |
operator.
Example:
const fs = require('fs');
const {
O_RDWR,
O_CREAT,
O_EXCL
} = fs.constants;
fs.open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => {
// ...
});
文件可访问性的常量#
以下常量适用于 fs.access()
。
常量 | 说明 |
---|---|
F_OK |
表明文件对调用进程可见。
这对于判断文件是否存在很有用,但对 rwx 权限没有任何说明。
如果未指定模式,则默认值为该值。
|
R_OK |
表明调用进程可以读取文件。 |
W_OK |
表明调用进程可以写入文件。 |
X_OK |
表明调用进程可以执行文件。
在 Windows 上无效(表现得像 fs.constants.F_OK )。
|
文件拷贝的常量#
以下常量适用于 fs.copyFile()
。
常量 | 说明 |
---|---|
COPYFILE_EXCL |
如果目标路径已存在,则拷贝操作将失败。 |
COPYFILE_FICLONE |
拷贝操作将尝试创建写时拷贝链接。 如果底层平台不支持写时拷贝,则使用备选的拷贝机制。 |
COPYFILE_FICLONE_FORCE |
拷贝操作将尝试创建写时拷贝链接。 如果底层平台不支持写时拷贝,则拷贝操作将失败。 |
文件打开的常量#
以下常量适用于 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 操作系统上可用。 在其他操作系统上,此标志会被忽略。 |
文件类型的常量#
以下常量适用于 fs.Stats
对象的 mode
属性,用于决定文件的类型。
常量 | 说明 |
---|---|
S_IFMT |
用于提取文件类型代码的位掩码。 |
S_IFREG |
表示普通的文件。 |
S_IFDIR |
表示目录。 |
S_IFCHR |
表示面向字符的设备文件。 |
S_IFBLK |
表示面向块的设备文件。 |
S_IFIFO |
表示 FIFO 或管道。 |
S_IFLNK |
表示符号链接。 |
S_IFSOCK |
表示套接字。 |
文件模式的常量#
以下常量适用于 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 |
表明其他人可执行。 |
文件系统标志#
当 flag
选项采用字符串时,则以下标志均可用:
-
'a'
: 打开文件用于追加。 如果文件不存在,则创建该文件。 -
'ax'
: 类似于'a'
,但如果路径存在,则失败。 -
'a+'
: 打开文件用于读取和追加。 如果文件不存在,则创建该文件。 -
'ax+'
: 类似于'a+'
,但如果路径存在,则失败。 -
'as'
: 打开文件用于追加(在同步模式中)。 如果文件不存在,则创建该文件。 -
'as+'
: 打开文件用于读取和追加(在同步模式中)。 如果文件不存在,则创建该文件。 -
'r'
: 打开文件用于读取。 如果文件不存在,则会发生异常。 -
'r+'
: 打开文件用于读取和写入。 如果文件不存在,则会发生异常。 -
'rs+'
: 打开文件用于读取和写入(在同步模式中)。 指示操作系统绕过本地的文件系统缓存。这对于在 NFS 挂载上打开文件时非常有用,因为它可以跳过可能过时的本地缓存。 它对 I/O 性能有非常实际的影响,因此不建议使用此标志(除非真的需要)。
这不会把
fs.open()
或fsPromises.open()
变成同步的阻塞调用。 如果需要同步的操作,则应使用fs.openSync()
之类的。 -
'w'
: 打开文件用于写入。 如果文件不存在则创建文件,如果文件存在则截断文件。 -
'wx'
: 类似于'w'
,但如果路径存在,则失败。 -
'w+'
: 打开文件用于读取和写入。 如果文件不存在则创建文件,如果文件存在则截断文件。 -
'wx+'
: 类似于'w+'
,但如果路径存在,则失败。
flag
也可以是数字,参见 open(2)
文档。
常用的常量可以从 fs.constants
获取。
在 Windows 上,标志会被转换为合适的等效标志,例如 O_WRONLY
转换为 FILE_GENERIC_WRITE
、 O_EXCL|O_CREAT
转换为能被 CreateFileW
接受的 CREATE_NEW
。
如果路径已经存在,则排他性标志 'x'
( open(2)
中的 O_EXCL
标志)会使操作返回错误。
在 POSIX 上,如果路径是符号链接,则使用 O_EXCL
也会返回错误(即使符号链接指向不存在的路径)。
排他性标志可能不适用于网络文件系统。
在 Linux 上,当以追加模式打开文件时,则写入时无法指定位置。 内核会忽略位置参数,并始终追加数据到文件的末尾。
如果要修改文件而不是覆盖文件,则 flag
选项需要被设置为 'r+'
而不是默认的 'w'
。
有些标志的行为是特定于平台的。
例如,在 macOS 和 Linux 上使用 'a+'
标志打开目录会返回错误。
但是,在 Windows 和 FreeBSD 上,则会返回文件描述符或 FileHandle
。
// 在 macOS 和 Linux 上:
fs.open('<目录>', 'a+', (err, fd) => {
// => [Error: EISDIR: illegal operation on a directory, open <目录>]
});
// 在 Windows 和 FreeBSD 上:
fs.open('<目录>', 'a+', (err, fd) => {
// => null, <fd>
});
在 Windows 上,使用 'w'
标志打开(通过 fs.open()
、 fs.writeFile()
或 fsPromises.open()
)现有的隐藏文件,则会抛出 EPERM
。
现有的隐藏文件可以使用 'r+'
标志打开用于写入。
调用 fs.ftruncate()
或 fsPromises.ftruncate()
可以用于重置文件的内容。