fs
模块使能够以一种模仿标准 POSIX 函数的方式与文件系统进行交互。
当 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+'
,但如果路径存在,则失败。
const fs = require('fs'); /** * 1. 打开文件 * 2. 写入内容 * 2. 关闭文件 */ fs.open('hello.txt', 'w', (err, fd) => { if (!err) { fs.write(fd, "hello", (err) => { if (!err) { fs.close(fd, (err => { if (!err) console.log('写入完毕,已关闭') })) } }) } }) /** * 简单文件写入 */ fs.writeFile('hello.txt', "hello", (err) => { if (!err) console.log('写入成功') }) /** * 流式文件写入 * 1. 创建一个可写流 */ const ws = fs.createWriteStream('hello2.txt') ws.once('open', () => { console.log('流打开') }) ws.once('close', () => { console.log('流关闭') }) ws.write("流式文件写入") ws.write("qwwwq") ws.write("qwwwq") // A=>B 关闭 B端,可能数据丢失 //ws.close() // A=>B 关闭 A端,数据接受完,在关闭 ws.end()
/** * 简单文件读取 * 文件过大时,有可能导致内存溢出 */ fs.readFile('hello.txt', (err,data) => { if (!err) { fs.writeFile('hello1.txt',data,(err)=>{ console.log('复制成功') }) } }) /** * 流式文件读取 * 1. 创建一个可写流 */ const rs = fs.createReadStream('hello2.txt') var ws= fs.createWriteStream('hello3.txt') rs.once('open', () => { console.log('流打开') }) rs.once('close', () => { console.log('流关闭') }) rs.on('data',(data)=>{ console.log(data); }) // 可以将流直接复制到可写流 rs.pipe(ws)
fs.existsSync(path)
fs.exists('/etc/passwd', (exists) => { console.log(exists ? '存在' : '不存在'); });
fs.stat(path[, options], callback)
fs.Stats
对象提供了关于文件的信息
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.unlink(path, callback)
异步地删除文件或符号链接。 除了可能的异常,完成回调没有其他参数。
fs.unlink()
对空或非空的目录均不起作用。 若要删除目录,则使用 fs.rmdir()
。
// 假设 '文件.txt' 是普通的文件。 fs.unlink('文件.txt', (err) => { if (err) throw err; console.log('文件已被删除'); });
fs.readdir(path[, options], callback)
读取目录的内容。 回调有两个参数 (err, files)
,其中 files
是目录中文件的名称的数组(不包括 '.'
和 '..'
)。
fs.truncate(path[, len], callback)
将文件修改为指定len 大小
fs.mkdir(path[, options], callback)
fs.rmdir(path[, options], callback)
创建 删除目录
fs.rename(oldPath, newPath, callback)
异步地把 oldPath
文件重命名为 newPath
提供的路径名。 如果 newPath
已存在,则覆盖它。 除了可能的异常,完成回调没有其他参数。
fs.watchFile(filename[, options], listener)
监视 filename
的更改。 每当访问文件时都会调用 listener
回调。
fs.watchFile('message.text', (curr, prev) => { console.log(`当前的最近修改时间是: ${curr.mtime}`); console.log(`之前的最近修改时间是: ${prev.mtime}`); });