一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
文件I/O
I/O:input/output,对外部设备的输入输出。
IO 的速度往往低于内存和 CPU 的交互速度。
磁盘、网卡、显卡、打印机...都是外部设备。
fs 模块
fs 模块中绝大部分 API 都是异步模式,跟计算机硬盘交互。
不推荐使用 Sync 模式进行操作,因为 Sync 函数是同步的,会导致JS运行阻塞,及其影响性能。
通常,在程序启动时运行有限次数即可。
在 ES6 的promise API 出现后,读取文件 api 变为了 Promise 模式。但是为了兼容性,仍然保留了 Sync 的 API。
- readFile:读取一个文件
- writeFile:向文件写入内容
- stat:获取文件或目录信息
- readdir:获取目录中的文件和子目录
- mkdir:创建目录
exists:判断文件或目录是否存在
读取一个目录中所有子目录和文件:
const fs = require('fs');
const path = require('path');
// 创建一个文件信息类
class File {
constructor(filename, name, ext, isFile, size, createTime, updateTime) {
this.filename = filename;
this.name = name;
this.ext = ext;
this.isFile = isFile;
this.size = size
this.createTime = createTime;
this.updateTime = updateTime;
}
static async getFile(filename) {
const stat = await fs.promises.stat(filename);
const name = path.basename(filename);
const ext = path.extname(filename);
const isFile = stat.isFile();
const size = stat.size;
const createTime = new Date(stat.birthtime);
const updateTime = new Date(stat.mtime);
return new File(filename, name, ext, isFile, size, createTime, updateTime)
}
async getContent(isBuffer = false) {
if (this.isFile) {
if (isBuffer) {
return await fs.promises.readFile(this.filename);
}
else{
return await fs.promises.readFile(this.filename, 'utf-8');
}
}
return null;
}
async getChildren(){
if (this.isFile) {
return [];
}
let children = await fs.promises.readdir(this.filename);
children = children.map(name => {
const res = path.resolve(this.filename, name);
return File.getFile(res)
})
return Promise.all(children) ;
}
}
// 读取文件信息
async function readDir(dirname){
const file = await File.getFile(dirname);
return await file.getChildren();
}
// 测试
async function test(){
const dirname = path.resolve(__dirname, "./myFiles");
const result = await readDir(dirname);
console.log(result);
}
test()
文件流
文件流是流的一种,当我们读取的文件不是一个文本文件而是一张图片或是音频...大体积文件。计算机硬盘的容量是非常大的,但是内存的空间却是有限的。如果直接读取的方式,那所有的数据都会被挤压在内存里面。我们不希望一次性全读出来,而是一部分一部分的读取。
流
流是指数据的流动,数据从一个地方缓缓的流动到另一个地方,这个过程就称为流。
流是有方向的,不同语言对流的含义不一样。在 node js里面分为:
- 可读流:数据从源头流向内存
- 可写流:数据从内存流向源头
- 双工流:数据即可从源头流向内存又可以从内存流向源头
使用流主要解决这些问题:其他介质和内存的数据规模不一致,其他介质和内存数据处理能力不一致。
文件流
内存数据和磁盘文件之间的流动
在 node 的stream 模块中有两个构造函数,Readable、Writable 来实现流。
文件流的创建
const fs = require("fs");
const path = require("path");
const filename = path.resolve(__dirname, "./abc.txt");
const rs = fs.createReadStream(filename, {
encoding: 'utf-8', // 编码方式
highWaterMark: 1, // 每次读取的大小,根据encoding值运算方式不同
autoClose: true, // 读完后会自动关闭
})
// 注册事件
fs.on("open", function () {
console.log('文件被打开')
})
fs.on('error', function(){
console.log('出错了')
})
fs.on('close', function(){
console.log('文件关闭')
})
fs.on('data', function(chunk){
console.log('读到了一部分数据', chunk)
})
fs.on('pause', function(){
console.log('暂停')
})
fs.on('resume', function(){
console.log('恢复')
})