Appearance
fs(file system)
文件操作的 API,有同步和异步。
阻塞的文件读写
阻塞的优点是速度快,可以马上拿到结果。缺点是后面的逻辑需要等待。
js
const fs = require('fs')
const path = require('path')
// 读取的数据默认的编码都是 null,即二进制数据(Buffer)。
// 如果文件不存在,报错。
const content = fs.readFileSync(path.resolve(__dirname, 'foo.md'))
// 写入操作也是二进制,不需要考虑编码问题。
// 如果文件不存在,会创建。如果文件存在,会覆盖。
fs.writeFileSync(path.relative(__dirname, 'bar.md'), content)非阻塞的文件读写
Node 中认为 64 KB 以下是小文件。
js
const fs = require('fs')
const path = require('path')
// 全部先读取到内存中,再写进去。
// 不能读取大文件,如果文件过大,会淹没可用内存或内存溢出。
fs.readFile(path.resolve(__dirname, '11-流.md'), function (err, data) {
if (err) {
return console.log(err)
}
fs.writeFile(path.resolve(__dirname, 'copy.md'), data, function (err) {
if (err) {
return console.log(err)
}
console.log('copy ok')
})
})js
const fs = require('fs')
const path = require('path')
const buffer = Buffer.alloc(3)
// r - read
// w - write
// a - append,追加内容,如果文件不存在会创建。
// r+ - 以读为基础,要求文件必须存在。
// w+ - 以写为基础,文件不存在也可以操作。
fs.open(path.resolve(__dirname, 'foo.md'), 'r', function (err, fd) {
// fd => file description,用来描述对这个文件做什么操作,是一个数字,从 3 开始递增。
// 读取文件,从 Buffer 的第 0 个位置写入,写 3 个,读取文件的位置是 0。
fs.read(fd, buffer, 0, 3, 0, function (err, bytesRead) {
// bytesRead 表示真实读取到的个数
// 销毁读取的结果
fs.open(path.resolve(__dirname, 'bar.md'), 'w', function (err, wfd) {
// 写入文件,从 Buffer 的第 0 个位置读取,读 3 个,写入文件的位置是 0。
fs.write(wfd, buffer, 0, 3, 0, function (err, written) {
console.log('write ok')
fs.close(fd, () => {})
fs.close(wfd, () => {})
})
})
})
})js
const fs = require('fs')
const path = require('path')
// 读取 3 个字节再消费 3 个字节 怎么实现?
const size = 3
const buffer = Buffer.alloc(size)
let readOffset = 0
let writeOffset = 0
// 读写可以分开操作,通过发布订阅来解耦。fs 基于流来实现大文件的读取。
// fs 中 createReadStream 和 createWriteStream 基于 Strem 模块实现。
fs.open(path.resolve(__dirname, 'foo.md'), 'r', function (err, fd) {
fs.open(path.resolve(__dirname, 'bar.md'), 'w', function (err, wfd) {
const next = function () {
fs.read(fd, buffer, 0, size, readOffset, function (err, bytesRead) {
fs.write(wfd, buffer, 0, bytesRead, writeOffset, function (err, written) {
console.log(bytesRead)
if (bytesRead) {
readOffset += bytesRead
writeOffset += written
next()
} else {
fs.close(fd, () => {})
fs.close(wfd, () => {})
}
})
})
}
next()
})
})