fs(文件系统)
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}`);
});