Node.js v12.14.0 文档
目录
- fs(文件系统)
- 文件路径
- 文件描述符
- 线程池的使用
- fs.Dir 类
- fs.Dirent 类
- fs.FSWatcher 类
- 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, flags], callback)
- [fs.copyFileSync(src, dest, flags])
- [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.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.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.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.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.readFile(options)
- [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, flags])
- fsPromises.lchmod(path, mode)
- fsPromises.lchown(path, uid, gid)
- 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.stat(path, options])
- [fsPromises.symlink(target, path, type])
- [fsPromises.truncate(path, len])
- fsPromises.unlink(path)
- fsPromises.utimes(path, atime, mtime)
- [fsPromises.writeFile(file, data, options])
- FS 常量
- 文件系统标志
fs(文件系统)#
稳定性: 2 - 稳定
fs
模块提供了一个 API,用于以模仿标准 POSIX 函数的方式与文件系统进行交互。
要使用此模块:
const fs = require('fs');
所有文件系统操作都具有同步和异步的形式。
异步的形式总是将完成回调作为其最后一个参数。 传给完成回调的参数取决于具体方法,但第一个参数始终预留用于异常。 如果操作成功完成,则第一个参数将为 null
或 undefined
。
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('已成功删除 /tmp/hello');
});
使用同步的操作发生的异常会立即抛出,可以使用 try…catch
处理,也可以允许冒泡。
const fs = require('fs');
try {
fs.unlinkSync('/tmp/hello');
console.log('已成功删除 /tmp/hello');
} catch (err) {
// 处理错误
}
使用异步的方法时无法保证顺序。 因此,以下的操作容易出错,因为 fs.stat()
操作可能在 fs.rename()
操作之前完成:
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
console.log('重命名完成');
});
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
要正确地排序这些操作,则将 fs.stat()
调用移动到 fs.rename()
操作的回调中:
fs.rename('/tmp/hello', '/tmp/world', (err) => {
if (err) throw err;
fs.stat('/tmp/world', (err, stats) => {
if (err) throw err;
console.log(`文件属性: ${JSON.stringify(stats)}`);
});
});
在繁忙的进程中,强烈建议使用这些调用的异步版本。 同步的版本将阻塞整个进程,直到它们完成(停止所有连接)。
虽然不推荐这样使用,但大多数 fs 函数允许省略回调参数,在这种情况下,使用一个会重新抛出错误的默认回调。 要获取原始调用点的跟踪,则设置 NODE_DEBUG
环境变量:
不推荐在异步的 fs 函数上省略回调函数,因为可能导致将来抛出错误。
$ cat script.js
function bad() {
require('fs').readFile('/');
}
bad();
$ env NODE_DEBUG=fs node script.js
fs.js:88
throw backtrace;
^
Error: EISDIR: illegal operation on a directory, read
<stack trace.>
文件路径#
大多数 fs
操作接受的文件路径可以指定为字符串、Buffer
、或使用 file:
协议的 URL
对象。
字符串形式的路径被解析为标识绝对或相对文件名的 UTF-8 字符序列。 相对路径将相对于 process.cwd()
指定的当前工作目录进行解析。
在 POSIX 上使用绝对路径的示例:
const fs = require('fs');
fs.open('/open/some/file.txt', 'r', (err, fd) => {
if (err) throw err;
fs.close(fd, (err) => {
if (err) throw err;
});
});
在 POSIX 上使用相对路径(相对于 process.cwd()
)的示例:
fs.open('file.txt', 'r', (err, fd) => {
if (err) throw err;
fs.close(fd, (err) => {
if (err) throw err;
});
});
使用 Buffer
指定的路径主要用于将文件路径视为不透明字节序列的某些 POSIX 操作系统。 在这样的系统上,单个文件路径可以包含使用多种字符编码的子序列。 与字符串路径一样, Buffer
路径可以是相对路径或绝对路径:
在 POSIX 上使用绝对路径的示例:
fs.open(Buffer.from('/open/some/file.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:///tmp/hello');
fs.readFileSync(fileUrl);
file:
URL 始终是绝对路径。
使用 WHATWG URL
对象可能会采用特定于平台的行为。
在 Windows 上,带有主机名的 file:
URL 转换为 UNC 路径,而带有驱动器号的 file:
URL 转换为本地绝对路径。 没有主机名和驱动器号的 file:
URL 将导致抛出错误:
// 在 Windows 上:
// - 带有主机名的 WHATWG 文件的 URL 转换为 UNC 路径。
// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file
fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
// - 带有驱动器号的 WHATWG 文件的 URL 转换为绝对路径。
// file:///C:/tmp/hello => C:\tmp\hello
fs.readFileSync(new URL('file:///C:/tmp/hello'));
// - 没有主机名的 WHATWG 文件的 URL 必须包含驱动器号。
fs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file'));
fs.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,使用时将导致抛出错误:
// 在其他平台上:
// - 不支持带有主机名的 WHATWG 文件的 URL。
// file://hostname/p/a/t/h/file => throw!
fs.readFileSync(new URL('file://hostname/p/a/t/h/file'));
// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute
// - WHATWG 文件的 URL 转换为绝对路径。
// file:///tmp/hello => /tmp/hello
fs.readFileSync(new URL('file:///tmp/hello'));
包含编码后的斜杆字符(%2F
)的 file:
URL 在所有平台上都将导致抛出错误:
// 在 Windows 上:
fs.readFileSync(new URL('file:///C:/p/a/t/h/%2F'));
fs.readFileSync(new URL('file:///C:/p/a/t/h/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
\ or / characters */
// 在 POSIX 上:
fs.readFileSync(new URL('file:///p/a/t/h/%2F'));
fs.readFileSync(new URL('file:///p/a/t/h/%2f'));
/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded
/ characters */
在 Windows 上,包含编码后的反斜杆字符(%5C
)的 file:
URL 将导致抛出错误:
// 在 Windows 上:
fs.readFileSync(new URL('file:///C:/path/%5C'));
fs.readFileSync(new URL('file:///C:/path/%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
,将会在关闭资源之后被解决。
dir.close(callback)#
异步地关闭目录的底层资源句柄。 随后的读取将会导致错误。
关闭资源句柄之后将会调用 callback
。
dir.closeSync()#
同步地关闭目录的底层资源句柄。 随后的读取将会导致错误。
dir.path#
此目录的只读路径,与提供给 fs.opendir()
、fs.opendirSync()
或 fsPromises.opendir()
的一样。
dir.read()#
通过 readdir(3)
异步地读取下一个目录项作为 fs.Dirent
。
读取完成之后,将会返回一个 Promise
,它被解决时将会返回 fs.Dirent
或 null
(如果没有更多的目录项要读取)。
此函数返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能会或可能不会包含在遍历的结果中。
dir.read(callback)#
通过 readdir(3)
异步地读取下一个目录项作为 fs.Dirent
。
读取完成之后,将会调用 callback
并传入 fs.Dirent
或 null
(如果没有更多的目录项要读取)。
此函数返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能会或可能不会包含在遍历的结果中。
dir.readSync()#
通过 readdir(3)
同步地读取下一个目录项作为 fs.Dirent
。
如果没有更多的目录项要读取,则将会返回 null
。
此函数返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能会或可能不会包含在遍历的结果中。
dirSymbol.asyncIterator#
通过 readdir(3)
异步地遍历目录,直到读取了所有的目录项。
异步迭代器返回的目录项始终为 fs.Dirent
。 dir.read()
中为 null
的情况会在内部处理。
有关示例,请参阅 fs.Dir
。
该迭代器返回的目录项不遵循操作系统的底层目录机制所提供的特定顺序。 遍历目录时添加或删除的目录项可能会或可能不会包含在遍历的结果中。
fs.Dirent 类#
目录项的表示形式,通过从 fs.Dir
中读取而返回。
此外,当使用 withFileTypes
选项设置为 true
调用 fs.readdir()
或 fs.readdirSync()
时,生成的数组将会填充 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
。
fs.FSWatcher 类#
成功调用 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' 事件#
当监视文件时发生错误时触发。 发生错误的 fs.FSWatcher
对象在事件处理函数中不再可用。
watcher.close()#
给定的 fs.FSWatcher
停止监视更改。 一旦停止,则 fs.FSWatcher
对象将不再可用。
fs.ReadStream 类#
成功调用 fs.createReadStream()
将会返回一个新的 fs.ReadStream
对象。
'close' 事件#
当 fs.ReadStream
的底层文件描述符已关闭时触发。
'open' 事件#
当 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()#
如果 fs.Stats
对象描述块设备,则返回 true
。
stats.isCharacterDevice()#
如果 fs.Stats
对象描述字符设备,则返回 true
。
stats.isDirectory()#
如果 fs.Stats
对象描述文件系统目录,则返回 true
。
stats.isFIFO()#
如果 fs.Stats
对象描述先进先出(FIFO)管道,则返回 true
。
stats.isFile()#
如果 fs.Stats
对象描述常规文件,则返回 true
。
stats.isSocket()#
如果 fs.Stats
对象描述套接字,则返回 true
。
stats.isSymbolicLink()#
如果 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 类#
'close' 事件#
当 WriteStream
的底层文件描述符已关闭时触发。
'open' 事件#
当 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
指定的文件或目录的权限。 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('myfile', (err) => {
if (!err) {
console.error('myfile 已存在');
return;
}
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.access('myfile', (err) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('myfile 不存在');
return;
}
throw err;
}
fs.open('myfile', 'r', (err, fd) => {
if (err) throw err;
readMyData(fd);
});
});
读取(推荐)
fs.open('myfile', 'r', (err, fd) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('myfile 不存在');
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
| | | 文件名或文件描述符。data
|options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'a'
。callback
err
异步地将数据追加到文件,如果文件尚不存在则创建该文件。 data
可以是字符串或 Buffer
。
fs.appendFile('message.txt', '追加的数据', (err) => {
if (err) throw err;
console.log('数据已追加到文件');
});
如果 options
是字符串,则它指定字符编码:
fs.appendFile('message.txt', '追加的数据', 'utf8', callback);
path
可以指定为已打开用于追加(使用 fs.open()
或 fs.openSync()
)的数字型文件描述符。 文件描述符不会自动关闭。
fs.open('message.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
| | | 文件名或文件描述符。data
|options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'a'
。
同步地将数据追加到文件,如果文件尚不存在则创建该文件。 data
可以是字符串或 Buffer
。
try {
fs.appendFileSync('message.txt', '追加的数据');
console.log('数据已追加到文件');
} catch (err) {
/* 处理错误 */
}
如果 options
是字符串,则它指定字符编码:
fs.appendFileSync('message.txt', '追加的数据', 'utf8');
path
可以指定为已打开用于追加(使用 fs.open()
或 fs.openSync()
)的数字型文件描述符。 文件描述符不会自动关闭。
let fd;
try {
fd = fs.openSync('message.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)#
版本历史
异步的 close(2)
。 除了可能的异常,完成回调没有其他参数。
fs.closeSync(fd)#
同步的 close(2)
。返回 undefined
。
fs.constants#
返回包含文件系统操作常用常量的对象。 当前定义的特定常量在 FS 常量中描述。
fs.copyFile(src, dest[, flags], callback)#
异步地将 src
拷贝到 dest
。 默认情况下,如果 dest
已经存在,则覆盖它。 除了可能的异常,回调函数没有其他参数。 Node.js 不保证拷贝操作的原子性。 如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
flags
是一个可选的整数,指定拷贝操作的行为。 可以创建由两个或更多个值按位或组成的掩码(比如 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');
// 默认情况下将创建或覆盖目标文件。
fs.copyFile('源文件.txt', '目标文件.txt', (err) => {
if (err) throw err;
console.log('源文件已拷贝到目标文件');
});
如果第三个参数是数字,则它指定 flags
:
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;
// 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
fs.copyFile('源文件.txt', '目标文件.txt', COPYFILE_EXCL, callback);
fs.copyFileSync(src, dest[, flags])#
同步地将 src
拷贝到 dest
。 默认情况下,如果 dest
已经存在,则覆盖它。 返回 undefined
。 Node.js 不保证拷贝操作的原子性。 如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
flags
是一个可选的整数,指定拷贝操作的行为。 可以创建由两个或更多个值按位或组成的掩码(比如 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');
// 默认情况下将创建或覆盖目标文件。
fs.copyFileSync('源文件.txt', '目标文件.txt');
console.log('源文件已拷贝到目标文件');
如果第三个参数是数字,则它指定 flags
:
const fs = require('fs');
const { COPYFILE_EXCL } = fs.constants;
// 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
fs.copyFileSync('源文件.txt', '目标文件.txt', COPYFILE_EXCL);
fs.createReadStream(path[, options])#
版本历史
path
| |options
|flags
参阅支持的文件系统标志。默认值:'r'
。encoding
默认值:null
。fd
默认值:null
。mode
默认值:0o666
。autoClose
默认值:true
。emitClose
默认值:false
。start
end
默认值:Infinity
。highWaterMark
默认值:64 * 1024
。- 返回:
与用于可读流的 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
可更改此行为。
const fs = require('fs');
// 从某个字符设备创建一个流。
const stream = fs.createReadStream('/dev/input/event0');
setTimeout(() => {
stream.close(); // 这可能不会关闭流。
// 人工标记流的结束,就像底层的资源自身已表明文件的结束一样,允许流进行关闭。
// 这不会取消挂起中的读取操作,如果存在此类操作,则过程可能仍无法成功地退出,直到完成。
stream.push(null);
stream.read(0);
}, 100);
如果 autoClose
为 false
,则即使出现错误,文件描述符也不会被关闭。 应用程序负责关闭它并确保没有文件描述符泄漏。 如果 autoClose
设为 true
(默认的行为),则在 'error'
或 'end'
事件时文件描述符将会被自动地关闭。
mode
用于设置文件模式(权限和粘滞位),但仅限于创建文件时。
示例,从一个大小为 100 个字节的文件中读取最后 10 个字节:
fs.createReadStream('sample.txt', { start: 90, end: 99 });
如果 options
是字符串,则它指定字符编码。
fs.createWriteStream(path[, options])#
版本历史
path
| |options
|flags
参阅支持的文件系统标志。默认值:'w'
。encoding
默认值:'utf8'
。fd
默认值:null
。mode
默认值:0o666
。autoClose
默认值:true
。emitClose
默认值:false
。start
- 返回:
options
可以包括 start
选项,允许在文件的开头之后的某个位置写入数据,允许的值在 [0, Number.MAX_SAFE_INTEGER
] 的范围内。 若要修改文件而不是覆盖它,则 flags
模式需要为 r+
而不是默认的 w
模式。 encoding
可以是 Buffer
接受的任何一种字符编码。
如果 autoClose
设置为 true
(默认的行为),则在 'error'
或 'finish'
事件时文件描述符将会被自动地关闭。 如果 autoClose
为 false
,则即使出现错误,文件描述符也不会被关闭。 应用程序负责关闭它并确保没有文件描述符泄漏。
默认情况下,流在销毁后将不会触发 'close'
事件。 这与其他 Writable
流的默认行为相反。 将 emitClose
选项设置为 true
可更改此行为。
与 ReadStream
类似,如果指定了 fd
,则 WriteStream
将会忽略 path
参数并将会使用指定的文件描述符。 这意味着不会触发 'open'
事件。 fd
必须是阻塞的,非阻塞的 fd
应该传给 net.Socket
。
如果 options
是字符串,则它指定字符编码。
fs.exists(path, callback)#
版本历史
稳定性: 0 - 废弃: 改为使用 fs.stat()
或 fs.access()
。
通过检查文件系统来测试给定的路径是否存在。 然后调用 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('/etc/passwd')) {
console.log('文件已存在');
}
fs.fchmod(fd, mode, callback)#
版本历史
异步的 fchmod(2)
。 除了可能的异常,完成回调没有其他参数。
fs.fchmodSync(fd, mode)#
同步的 fchmod(2)
。返回 undefined
。
fs.fchown(fd, uid, gid, callback)#
版本历史
异步的 fchown(2)
。 除了可能的异常,完成回调没有其他参数。
fs.fchownSync(fd, uid, gid)#
同步的 fchown(2)
。返回 undefined
。
fs.fdatasync(fd, callback)#
版本历史
异步的 fdatasync(2)
。 除了可能的异常,完成回调没有其他参数。
fs.fdatasyncSync(fd)#
同步的 fdatasync(2)
。返回 undefined
。
fs.fstat(fd[, options], callback)#
版本历史
fd
options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。callback
err
stats
异步的 fstat(2)
。 回调会传入两个参数 (err, stats)
,其中 stats
是 fs.Stats
对象。 fstat()
与 stat()
相同,除了文件是由文件描述符 fd
指定。
fs.fstatSync(fd[, options])#
版本历史
fd
options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。- 返回:
同步的 fstat(2)
。
fs.fsync(fd, callback)#
版本历史
异步的 fsync(2)
。 除了可能的异常,完成回调没有其他参数。
fs.fsyncSync(fd)#
同步的 fsync(2)
。返回 undefined
。
fs.ftruncate(fd[, len], callback)#
版本历史
异步的 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)#
版本历史
更改文件描述符指向的对象的文件系统时间戳。 参阅 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)#
废弃于: v0.4.7
同步的 lchmod(2)
。返回 undefined
。
fs.lchown(path, uid, gid, callback)#
版本历史
异步的 lchown(2)
。 除了可能的异常,完成回调没有其他参数。
fs.lchownSync(path, uid, gid)#
版本历史
同步的 lchown(2)
。返回 undefined
。
fs.link(existingPath, newPath, callback)#
版本历史
异步的 link(2)
。 除了可能的异常,完成回调没有其他参数。
fs.linkSync(existingPath, newPath)#
版本历史
同步的 link(2)
。返回 undefined
。
fs.lstat(path[, options], callback)#
版本历史
path
| |options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。callback
err
stats
异步的 lstat(2)
。 回调会传入两个参数 (err, stats)
,其中 stats
是 fs.Stats
对象。 lstat()
与 stat()
相同,只是如果 path
是符号链接,则查看的是链接自身,而不是它指向的文件。
fs.lstatSync(path[, options])#
版本历史
path
| |options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。- 返回:
同步的 lstat(2)
。
fs.mkdir(path[, options], callback)#
版本历史
异步地创建目录。 除了可能的异常,完成回调没有其他参数。
可选的 options
参数可以是指定模式(权限和粘滞位)的整数,也可以是具有 mode
属性和 recursive
属性(指示是否应创建父文件夹)的对象。
// 创建 /tmp/a/apple 目录,无论是否存在 /tmp 和 /tmp/a 目录。
fs.mkdir('/tmp/a/apple', { 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
。 fs.mkdir()
的同步版本。
也可参阅 mkdir(2)
。
fs.mkdtemp(prefix[, options], callback)#
版本历史
创建一个唯一的临时目录。
生成要附加在必需的 prefix
后面的六位随机字符,以创建唯一的临时目录。 由于平台的不一致性,请避免在 prefix
中以 X
字符结尾。 在某些平台上,特别是 BSD,可以返回六个以上的随机字符,并用随机字符替换 prefix
中结尾的 X
字符。
创建的目录路径作为字符串传给回调的第二个参数。
可选的 options
参数可以是指定字符编码的字符串,也可以是具有指定要使用的字符编码的 encoding
属性的对象。
fs.mkdtemp(path.join(os.tmpdir(), '目录-'), (err, folder) => {
if (err) throw err;
console.log(folder);
// 打印: /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, folder) => {
if (err) throw err;
console.log(folder);
// 输出类似 `/tmpabc123`。
// 新的临时目录会被创建在文件系统根目录,而不是在 /tmp 目录中。
});
// 此用法是正确的:
const { sep } = require('path');
fs.mkdtemp(`${tmpDir}${sep}`, (err, folder) => {
if (err) throw err;
console.log(folder);
// 输出类似 `/tmp/abc123`。
// 新的临时目录会被创建在 /tmp 目录中。
});
fs.mkdtempSync(prefix[, options])#
返回创建的目录路径。
有关详细信息,请参阅此 API 异步版本的文档:fs.mkdtemp()
。
可选的 options
参数可以是指定字符编码的字符串,也可以是具有指定要使用的字符编码的 encoding
属性的对象。
fs.open(path[, flags[, mode]], callback)#
版本历史
path
| |flags
| 参阅支持的文件系统标志。默认值:'r'
。mode
默认值:0o666
(可读写)。callback
err
fd
异步地打开文件。参阅 open(2)
。
mode
用于设置文件模式(权限和粘滞位),但仅限于创建文件时。 在 Windows 上,只能操作写权限,参阅 fs.chmod()
。
回调有两个参数 (err, fd)
。
有些字符 (< > : " / \ | ? *
) 在 Windows 上是预留的,参阅命名文件、路径以及命名空间。 在 NTFS 上,如果文件名包含冒号,则 Node.js 将打开文件系统流,参阅此 MSDN 页面。
基于 fs.open()
的函数也表现出以上行为,比如 fs.writeFile()
、 fs.readFile()
等。
fs.opendir(path[, options], callback)#
异步地打开目录。 参阅 opendir(3)
。
创建一个 fs.Dir
,其中包含所有用于更进一步读取和清理目录的的函数。
encoding
选项用于在打开目录和后续的读取操作时设置 path
的字符编码。
fs.opendirSync(path[, options])#
同步地打开目录。 参阅 opendir(3)
。
创建一个 fs.Dir
,其中包含所有用于更进一步读取和清理目录的的函数。
encoding
选项用于在打开目录和后续的读取操作时设置 path
的字符编码。
fs.openSync(path[, flags, mode])#
版本历史
path
| |flags
| 默认值:'r'
。参阅支持的文件系统标志。mode
默认值:0o666
。- 返回:
返回表示文件描述符的整数。
有关详细信息,参阅此 API 的异步版本的文档:fs.open()
。
fs.read(fd, buffer, offset, length, position, callback)#
版本历史
从 fd
指定的文件中读取数据。
buffer
是数据将写入的缓冲区。
offset
是 buffer 中开始写入的偏移量。
length
是一个整数,指定要读取的字节数。
position
参数指定从文件中开始读取的位置。 如果 position
为 null
,则从当前文件位置读取数据,并更新文件位置。 如果 position
是整数,则文件位置将保持不变。
回调有三个参数 (err, bytesRead, buffer)
。
如果调用此方法的 util.promisify()
版本,则返回的 Promise
会返回具有 bytesRead
属性和 buffer
属性的 Object
。
fs.readdir(path[, options], callback)#
版本历史
异步的 readdir(3)
。 读取目录的内容。 回调有两个参数 (err, files)
,其中 files
是目录中的文件名的数组(不包括 '.'
和 '..'
)。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性的对象,该属性指定用于传给回调的文件名的字符编码。 如果 encoding
设置为 'buffer'
,则返回的文件名是 Buffer
对象。
如果 options.withFileTypes
设置为 true
,则 files
数组将包含 fs.Dirent
对象。
fs.readdirSync(path[, options])#
版本历史
同步的 readdir(3)
。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性的对象,该属性指定用于传给回调的文件名的字符编码。 如果 encoding
设置为 'buffer'
,则返回的文件名是 Buffer
对象。
如果 options.withFileTypes
设置为 true
,则返回的结果将包含 fs.Dirent
对象。
fs.readFile(path[, options], callback)#
版本历史
path
| | | 文件名或文件描述符。options
|encoding
| 默认值:null
。flag
参阅支持的文件系统标志。默认值:'r'
。callback
err
data
|
异步地读取文件的全部内容。
fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
回调会传入两个参数 (err, data)
,其中 data
是文件的内容。
如果没有指定 encoding
,则返回原始的 buffer。
如果 options
是字符串,则它指定字符编码:
fs.readFile('/etc/passwd', 'utf8', callback);
当 path
是目录时, 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
| | | 文件名或文件描述符。options
|encoding
| 默认值:null
。flag
参阅支持的文件系统标志。默认值:'r'
。- 返回: |
返回 path
的内容。
有关详细信息,参阅此 API 的异步版本的文档:fs.readFile()
。
如果指定了 encoding
选项,则此函数返回字符串,否则返回 buffer。
与 fs.readFile()
类似,当 path
是目录时, fs.readFileSync()
的行为是特定于平台的。
// 在 macOS、Linux 和 Windows 上:
fs.readFileSync('<目录>');
// => [Error: EISDIR: illegal operation on a directory, read <目录>]
// 在 FreeBSD 上:
fs.readFileSync('<目录>'); // => <data>
fs.readlink(path[, options], callback)#
版本历史
异步的 readlink(2)
。 回调会传入两个参数 (err, linkString)
。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性的对象,该属性指定用于传递给回调的链接路径的字符编码。 如果 encoding
设置为 'buffer'
,则返回的链接路径将作为 Buffer
对象传入。
fs.readlinkSync(path[, options])#
版本历史
同步的 readlink(2)
。 返回符号链接的字符串值。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性的对象,该属性指定用于传递给回调的链接路径的字符编码。 如果 encoding
设置为 'buffer'
,则返回的链接路径将作为 Buffer
对象传入。
fs.readSync(fd, buffer, offset, length, position)#
版本历史
返回 bytesRead
的数量。
有关详细信息,请参阅此 API 异步版本的文档:fs.read()
。
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.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.rename(oldPath, newPath, callback)#
版本历史
异步地将 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)#
版本历史
稳定性: 1 - 递归的删除是实验性的。
path
| |options
emfileWait
如果遇到EMFILE
错误,则 Node.js 将会在每次尝试时以 1 毫秒的线性回退重试该操作,直到超时持续时间超过此限制。 如果recursive
选项不为true
,则忽略此选项。默认值:1000
。maxBusyTries
如果遇到EBUSY
、ENOTEMPTY
或EPERM
错误,则 Node.js 将会在每次尝试时以 100 毫秒的线性回退等待重试该操作。 此选项代表重试的次数。如果recursive
选项不为true
,则忽略此选项。默认值:3
。recursive
如果为true
,则执行递归的目录删除。在递归模式中,如果path
不存在则不报告错误,并且在失败时重试操作。默认值:false
。callback
err
异步的 rmdir(2)
。 除了可能的异常,完成回调没有其他参数。
在文件(而不是目录)上使用 fs.rmdir()
会导致在 Windows 上出现 ENOENT
错误、在 POSIX 上出现 ENOTDIR
错误。
fs.rmdirSync(path[, options])#
版本历史
稳定性: 1 - 递归的删除是实验性的。
同步的 rmdir(2)
。 返回 undefined
。
在文件(而不是目录)上使用 fs.rmdirSync()
会导致在 Windows 上出现 ENOENT
错误、在 POSIX 上出现 ENOTDIR
错误。
fs.stat(path[, options], callback)#
版本历史
path
| |options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。callback
err
stats
异步的 stat(2)
。 回调有两个参数 (err, stats)
,其中 stats
是一个 fs.Stats
对象。
如果出现错误,则 err.code
将是常见系统错误之一。
不建议在调用 fs.open()
、 fs.readFile()
或 fs.writeFile()
之前使用 fs.stat()
检查文件是否存在。 而是应该直接打开、读取或写入文件,如果文件不可用则处理引发的错误。
要检查文件是否存在但随后并不对其进行操作,则建议使用 fs.access()
。
例如,给定以下的文件夹结构:
- txtDir
-- file.txt
- app.js
以下程序将会检查给定路径的统计信息:
const fs = require('fs');
const pathsToCheck = ['./txtDir', './txtDir/file.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
| |options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。- 返回:
同步的 stat(2)
。
fs.symlink(target, path[, type], callback)#
版本历史
异步的 symlink(2)
,它会创建名为 path
的链接,该链接指向 target
。 除了可能的异常,完成回调没有其他参数。
type
参数仅在 Windows 上可用,在其他平台上则会被忽略。 它可以被设置为 'dir'
、 'file'
或 'junction'
。 如果未设置 type
参数,则 Node 将会自动检测 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/file.txt' 是常规文件。
fs.unlink('path/file.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
的变化。 如果指定了 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
参数遵循以下规则:
- 值可以是表示 Unix 纪元时间的数字、
Date
对象、或类似'123456789.0'
的数值字符串。 - 如果该值无法转换为数值、或值为
NaN
、Infinity
或-Infinity
,则抛出错误。
fs.utimesSync(path, atime, mtime)#
版本历史
返回 undefined
。
有关详细信息,参阅此 API 的异步版本的文档:fs.utimes()
。
fs.watch(filename[, options][, listener])#
版本历史
filename
| |options
|persistent
指示如果文件已正被监视,进程是否应继续运行。默认值:true
。recursive
指示应该监视所有子目录,还是仅监视当前目录。这适用于监视目录时,并且仅适用于受支持的平台(参阅注意事项)。默认值:false
。encoding
指定用于传给监听器的文件名的字符编码。默认值:'utf8'
。listener
| 默认值:undefined
。eventType
filename
|- 返回:
监视 filename
的更改,其中 filename
是文件或目录。
第二个参数是可选的。 如果 options
传入字符串,则它指定 encoding
。 否则, options
应传入对象。
监听器回调有两个参数 (eventType, filename)
。 eventType
是 'rename'
或 'change'
, filename
是触发事件的文件的名称。
在大多数平台上,每当文件名在目录中出现或消失时,就会触发 'rename'
事件。
监听器回调绑定在由 fs.FSWatcher
触发的 'change'
事件上,但它与 eventType
的 'change'
值不是一回事。
注意事项#
fs.watch
的 API 在各个平台上并非 100% 一致,在某些情况下不可用。
仅在 macOS 和 Windows 上支持 recursive
选项。
可用性#
此特性取决于底层操作系统,提供了一种通知文件系统更改的方法。
- 在 Linux 系统上,使用
inotify(7)
。 - 在 BSD 系统上,使用
kqueue(2)
。 - 在 macOS 系统上,对文件使用
kqueue(2)
,对目录使用FSEvents
。 - 在 SunOS 系统上(包括 Solaris 和 SmartOS),使用事件端口。
- 在 Windows 系统上,此特性取决于
ReadDirectoryChangesW
。 - 在 Aix 系统上,此特性取决于
AHAFS
必须启动。
如果底层功能由于某些原因不可用,则 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
的更改。 每当访问文件时都会调用 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
的实例。
要在修改文件(而不仅仅是访问)时收到通知,则需要比较 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()
正在监视的文件消失并重新出现时,第二次回调事件(文件重新出现)返回的 previousStat
会与第一次回调事件(文件消失)返回的 previousStat
相同。
这种情况发生在:
- 文件被删除,然后又恢复。
- 文件被重命名,然后再第二次重命名回其原来的名称。
fs.write(fd, buffer[, offset[, length[, position]]], callback)#
版本历史
将 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)#
版本历史
将 string
写入到 fd
指定的文件。 如果 string
不是一个字符串,则该值会被强制转换为字符串。
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
| | | 文件名或文件描述符。data
| | |options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'w'
。callback
err
当 file
是一个文件名时,异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。 data
可以是字符串或 buffer。
当 file
是一个文件描述符时,行为类似于直接调用 fs.write()
(建议使用)。 请参阅以下有关使用文件描述符的说明。
如果 data
是一个 buffer,则 encoding
选项会被忽略。
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
| | | 文件名或文件描述符。data
| | |options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'w'
。
返回 undefined
。
有关详细信息,参阅此 API 的异步版本的文档:fs.writeFile()
。
fs.writeSync(fd, buffer[, offset[, length[, position]]])#
版本历史
有关详细信息,参阅此 API 的异步版本的文档:fs.write(fd, buffer...)
。
fs.writeSync(fd, string[, position[, encoding]])#
版本历史
有关详细信息,参阅此 API 的异步版本的文档: fs.write(fd, string...)
。
fs.writev(fd, buffers[, position], callback)#
使用 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])#
有关详细信息,参阅此 API 的异步版本的文档:fs.writev()
。
fs 的 Promise API#
fs.promises
API 提供了一组备用的异步文件系统的方法,它们返回 Promise
对象而不是使用回调。 API 可通过 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)#
data
|options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
flag
参阅支持的文件系统标志。默认值:'a'
。- 返回:
异步地将数据追加到文件,如果文件尚不存在则创建该文件。 data
可以是字符串或 Buffer
。 Promise
将会在成功时解决,且不带参数。
如果 options
是字符串,则它指定字符编码。
FileHandle
必须被打开用以追加。
filehandle.chmod(mode)#
更改文件的权限。 Promise
将会在成功时解决,且不带参数。
filehandle.chown(uid, gid)#
更改文件的所有者,然后在成功时解决 Promise
且不带参数。
filehandle.close()#
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()#
异步的 fdatasync(2)
。 Promise
将会在成功时解决,且不带参数。
filehandle.fd#
filehandle.read(buffer, offset, length, position)#
从文件中读取数据。
buffer
是数据将写入的缓冲区。
offset
是 buffer 中开始写入的偏移量。
length
是一个整数,指定要读取的字节数。
position
参数指定从文件中开始读取的位置。 如果 position
为 null
,则从当前文件位置读取数据,并更新文件位置。 如果 position
是整数,则文件位置将保持不变。
成功读取之后, Promise
会被解决并带上一个对象,对象上有一个 bytesRead
属性(指定读取的字节数)和一个 buffer
属性(指向传入的 buffer
参数)。
filehandle.readFile(options)#
options
|encoding
| 默认值:null
flag
参阅支持的文件系统标志。默认值:'r'
。- 返回:
异步地读取文件的全部内容。
Promise
被解决时会带上文件的内容。 如果没有指定字符编码(使用 options.encoding
),则数据会以 Buffer
对象返回。 否则,数据将会是一个字符串。
如果 options
是字符串,则它指定字符编码。
当 path
是目录时, fsPromises.readFile()
的行为是特定于平台的。 在 macOS、Linux 和 Windows 上,promise 将会被拒绝并带上一个错误。 在 FreeBSD 上,则将会返回目录内容的表示。
FileHandle
必须支持读取。
如果对文件句柄进行了一次或多次 filehandle.read()
调用,然后再调用 filehandle.readFile()
,则将从当前位置读取数据,直到文件结束。 它并不总是从文件的开头读取。
filehandle.stat([options])#
版本历史
options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。- 返回:
检索文件的 fs.Stats
。
filehandle.sync()#
异步的 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
写入到文件。
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
不是一个字符串,则该值会被强制转换为字符串。
Promise
会被解决并带上一个对象,对象包含一个 bytesWritten
属性(指定写入的字节数)和一个 buffer
属性(指向写入的 string
)。
position
指定文件开头的偏移量(数据应该被写入的位置)。 如果 position
的类型不是一个 number
,则数据会被写入当前的位置。 参阅 pwrite(2)
。
encoding
是期望的字符串编码。
在同一个文件上多次使用 filehandle.write()
且不等待 Promise
被解决(或被拒绝)是不安全的。 对于这种情况,建议使用 fs.createWriteStream()
。
在 Linux 上,当以追加模式打开文件时,写入无法指定位置。 内核会忽略位置参数,并始终将数据追加到文件的末尾。
filehandle.writeFile(data, options)#
data
| |options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'w'
。- 返回:
异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。 data
可以是字符串或 buffer。 Promise
将会在成功时解决,且不带参数。
如果 data
是一个 buffer,则 encoding
选项会被忽略。
如果 options
是一个字符串,则它指定字符编码。
FileHandle
必须支持写入。
在同一个文件上多次使用 filehandle.writeFile()
且不等待 Promise
被解决(或被拒绝)是不安全的。
如果对文件句柄进行了一次或多次 filehandle.write()
调用,然后再调用 filehandle.writeFile()
,则将从当前位置写入数据,直到文件结束。 它并不总是从文件的开头写入。
filehandle.writev(buffers[, position])#
将 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
| | | 文件名或FileHandle
。data
|options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'a'
。- 返回:
异步地将数据追加到文件,如果文件尚不存在则创建该文件。 data
可以是字符串或 Buffer
。 Promise
将会在成功时解决,且不带参数。
如果 options
是字符串,则它指定字符编码。
path
可以指定为已打开用于追加(使用 fsPromises.open()
)的 FileHandle
。
fsPromises.chmod(path, mode)#
更改文件的权限,然后在成功时解决 Promise
且不带参数。
fsPromises.chown(path, uid, gid)#
更改文件的所有者,然后在成功时解决 Promise
且不带参数。
fsPromises.copyFile(src, dest[, flags])#
异步地将 src
拷贝到 dest
。 默认情况下,如果 dest
已经存在,则覆盖它。 Promise
将会在成功时解决,且不带参数。
Node.js 不保证拷贝操作的原子性。 如果在打开目标文件用于写入后发生错误,则 Node.js 将尝试删除目标文件。
flags
是一个可选的整数,指定拷贝操作的行为。 可以创建由两个或更多个值按位或组成的掩码(比如 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 fsPromises = require('fs').promises;
// 默认情况下将创建或覆盖目标文件。
fsPromises.copyFile('源文件.txt', '目标文件.txt')
.then(() => console.log('源文件已拷贝到目标文件'))
.catch(() => console.log('该文件无法拷贝'));
如果第三个参数是数字,则它指定 flags
:
const fs = require('fs');
const fsPromises = fs.promises;
const { COPYFILE_EXCL } = fs.constants;
// 通过使用 COPYFILE_EXCL,如果目标文件存在,则操作将失败。
fsPromises.copyFile('源文件.txt', '目标文件.txt', COPYFILE_EXCL)
.then(() => console.log('源文件已拷贝到目标文件'))
.catch(() => console.log('该文件无法拷贝'));
fsPromises.lchmod(path, mode)#
废弃于: v10.0.0
更改符号链接的权限,然后在成功时解决 Promise
且不带参数。 此方法仅在 macOS 上实现。
fsPromises.lchown(path, uid, gid)#
版本历史
更改符号链接的拥有者,然后在成功时解决 Promise
且不带参数。
fsPromises.link(existingPath, newPath)#
异步的 link(2)
。 Promise
将会在成功时解决,且不带参数。
fsPromises.lstat(path[, options])#
版本历史
path
| |options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。- 返回:
异步的 lstat(2)
。 Promise
会被解决并带上用于给定的符号链接 path
的 fs.Stats
对象。
fsPromises.mkdir(path[, options])#
异步地创建目录,然后在成功时解决 Promise
且不带参数。
可选的 options
参数可以是指定模式(权限和粘滞位)的整数,也可以是具有 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
| |flags
| 参阅支持的文件系统标志。默认值:'r'
。mode
默认值:0o666
(可读写)。- 返回:
异步地打开文件并返回一个 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
对象。
fsPromises.readFile(path[, options])#
path
| | | 文件名或FileHandle
。options
|encoding
| 默认值:null
。flag
参阅支持的文件系统标志。默认值:'r'
。- 返回:
异步地读取文件的全部内容。
Promise
被解决时会带上文件的内容。 如果没有指定字符编码(使用 options.encoding
),则数据会以 Buffer
对象返回。 否则,数据将会是一个字符串。
如果 options
是字符串,则它指定字符编码。
当 path
是目录时, fsPromises.readFile()
的行为是特定于平台的。 在 macOS、Linux 和 Windows 上,promise 将会被拒绝并带上一个错误。 在 FreeBSD 上,则将会返回目录内容的表示。
指定的 FileHandle
必须支持读取。
fsPromises.readlink(path[, options])#
异步的 readlink(2)
。 Promise
会在成功时解决,且带上 linkString
。
可选的 options
参数可以是指定编码的字符串,也可以是具有 encoding
属性的对象,该属性指定用于链接路径的字符编码。 如果 encoding
设置为 'buffer'
,则返回的链接路径将作为 Buffer
对象传入。
fsPromises.realpath(path[, options])#
使用与 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])#
版本历史
稳定性: 1 - 递归的删除是实验性的。
path
| |options
emfileWait
如果遇到EMFILE
错误,则 Node.js 将会在每次尝试时以 1 毫秒的线性回退重试该操作,直到超时持续时间超过此限制。 如果recursive
选项不为true
,则忽略此选项。默认值:1000
。maxBusyTries
如果遇到EBUSY
、ENOTEMPTY
或EPERM
错误,则 Node.js 将会在每次尝试时以 100 毫秒的线性回退等待重试该操作。 此选项代表重试的次数。如果recursive
选项不为true
,则忽略此选项。默认值:3
。recursive
如果为true
,则执行递归的目录删除。在递归模式中,如果path
不存在则不报告错误,并且在失败时重试操作。默认值:false
。- 返回:
删除 path
指定的目录,然后在成功时解决 Promise
且不带参数。
在文件(而不是目录)上使用 fsPromises.rmdir()
会导致 Promise
被拒绝,在 Windows 上会带上 ENOENT
错误、在 POSIX 上会带上 ENOTDIR
错误。
fsPromises.stat(path[, options])#
版本历史
path
| |options
bigint
返回的fs.Stats
对象中的数值是否应为bigint
型。默认值:false
。- 返回:
Promise
会被解决并带上 fs.Stats
对象(用于给定的 path
)。
fsPromises.symlink(target, path[, type])#
创建一个符号链接,然后在成功时解决 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
指向的对象的文件系统时间戳,然后在成功时解决 Promise
且不带参数。
atime
和 mtime
参数遵循以下规则:
- 值可以是表示 Unix 纪元时间的数字、
Date
对象、或类似'123456789.0'
的数值字符串。 - 如果该值无法转换为数值、或值为
NaN
、Infinity
或-Infinity
,则抛出Error
。
fsPromises.writeFile(file, data[, options])#
file
| | | 文件名或FileHandle
。data
| |options
|encoding
| 默认值:'utf8'
。mode
默认值:0o666
。flag
参阅支持的文件系统标志。默认值:'w'
。- 返回:
异步地将数据写入到一个文件,如果文件已存在则覆盖该文件。 data
可以是字符串或 buffer。 Promise
将会在成功时解决,且不带参数。
如果 data
是一个 buffer,则 encoding
选项会被忽略。
如果 options
是一个字符串,则它指定字符编码。
指定的 FileHandle
必须支持写入。
在同一个文件上多次使用 fsPromises.writeFile()
且不等待 Promise
被解决(或被拒绝)是不安全的。
FS 常量#
以下常量由 fs.constants
输出。
并非所有操作系统都可以使用每个常量。
文件可访问性的常量#
以下常量适用于 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 系统上,即使路径是一个符号链接且指向一个不存在的文件,它也会被视为已存在。 该特有标志不一定适用于网络文件系统。
在 Linux 上,当以追加模式打开文件时,写入无法指定位置。 内核会忽略位置参数,并始终将数据追加到文件的末尾。
如果要修改文件而不是覆盖文件,则标志模式应为 '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()
可以用于重置文件的内容。