一、Buffer
1. 什么是Buffer?
1)缓冲区Buffer是暂时存放输入/输出数据的一段内存。
2)JS语言没有二进制数据类型,而在处理TCP和文件流的时候,必须要处理二进制数据。
3)NodeJS提供了一个Buffer对象来提供对二进制数据的操作。
4)Buffer是一个表示固定内存分配的全局对象,也就是说要放到缓存区中的字节数需要提前确定。
5)Buffer就好比由一个8位字节元素组成的数组,可以有效的在JavasScript中表示二进制数据。
2. 什么是字节?
1)字节(Byte)是计算机存储时的一种计量单位,一个字节等于8位二进制数。
2)一个位就代表一个0或1,每8个位(bit)组成一个字节(Byte)。
3)字节是通过网络传输信息的单位。
4)一个字节最大值十进制数是255。
5)单位:
8位 = 1字节
1024字节 = 1K
1024K = 1M
1024M = 1G
1024G = 1T
3. 定义Buffer的3种方式
(1) 通过长度定义buffer
// alloc
// 创建一个长度为 10、且用 0 填充的 Buffer
const buf1 = Buffer.alloc(10);
// 创建一个长度为 10、且用 0x1 填充的 Buffer
const buf2 = Buffer.alloc(10, 1);
// 创建一个长度为 10、且未初始化的 Buffer
const buf3 = Buffer.allocUnsafe(10);
(2) 通过数组定义buffer
// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer
const buf4 = Buffer.from([1, 2, 3]);
(3) 通过字符串定义buffer
const buf5 = Buffer.from('西西');
buf5.toString()
4. buffer常用方法
1)buf.fill(value, offset, end, encoding)
手动初始化,一般用于将buffer内容清0
buf.fill(0);
buf.fill('西', 0, 3, 'utf-8');
buf.fill('九', 3, 6, 'utf-8');
2)buf.write(string, offset, length, encoding)
buf.write('张', 0, 3, 'utf-8');
buf.write('国', 3, 3, 'utf-8');
3)isBuffer
判断是否是buffer
buf.isBuffer()
4)length
获取字节长度(显示的是字符串所代表的buffer的长度)
Buffer.byteLength("引擎");
buffer.length;
二、FS模块
1. 什么是fs模块?
1)在Node.js中,使用fs模块来实现所有有关文件及目录的创建、写入及删除操作。
2)在fs模块中,所有的方法都分为同步和异步两种实现。
3)具有sync后缀的方法为同步方法,不具有sync后缀的方法为异步方法。
2. 读取文件
(1) 同步读取
fs.readFileSync(path, [options])
let fs = require('fs');
let fd = fs.readFileSync(__dirname + "/source/a.txt");
console.log(fd);
console.log(fd.toString());
console.log("后续的操作");
(2) 异步读取
fs.readFile(path, [options], callback)
let fs = require('fs');
fs.readFile(__dirname + "/source/a.txt", (err, data) => {
if (!err) {
console.log(data);
console.log(data.toString());
}
});
console.log("后续的操作");
3. 写入文件
(1) 同步写入
fs.writeFileSync(file, data, [options])
// 1. 引入fs模块
let fs = require('fs');
// 2. 同步打开文件(openSync)
//let fd = fs.openSync(__dirname + "/source/b.txt", "w");
let fd = fs.openSync(__dirname + "/source/b.txt", "a");
// 3. 同步写入内容(writeFileSync)
fs.writeFileSync(fd, "我是西西");
// 4. 保存并推出(closeSync)
fs.closeSync(fd);
// 5. 后续操作
console.log("后续的操作");
(2) 异步写入
fs.writeFile(file, data, [options], callback)
options:
encoding
flag:默认 = ‘w’
mode:读写权限,默认为0666。
let fs = require('fs');
// 1.打开文件
let fd = fs.open(__dirname + "/source/c.txt", "a", (err, fd) => {
if (!err) {
// 2.写入文件
fs.writeFile(fd, `小九真好看!${new Date()} \n`, (err) => {
if (!err) {
console.log("写入文件成功!");
// 3.关闭文件
fs.close(fd, (err) => {
if (!err) {
console.log("关闭文件成功!");
} else {
throw err;
}
})
} else {
throw err;
}
})
} else {
throw err;
}
});
// 4.后续的操作
console.log("后续操作");
4. 拷贝文件
结合读与写操作
let fs = require('fs');
let copy = (src, target, callBack) => {
fs.readFile(src, (err, data) => {
if (!err) { //读取成功
fs.writeFile(target, data, {flag: 'a'}, (err, data) => {
if (!err) { //写入成功
callBack && callBack(err, data);
} else {
throw err;
}
} );
} else {
throw err;
}
});
};
copy(__dirname + "/source/girl.jpg", __dirname + "/target/two.jpg", (err, data) => {
if (!err) {
console.log("拷贝成功!");
} else {
console.log("拷贝失败!");
}
});
三、Stream
1. 什么是流?
1)流是一组有序的,有起点和终点的字节数据传输手段。
2)它不关心文件的整体内容,只关注是否从文件中读到了数据,以及读到数据之后的处理。
3)流是一个抽象接口,被 Node 中的很多对象所实现;比如HTTP 服务器request和response对象都是流。
2. 可读流createReadStream
(1) 创建可读流
// 1.创建一个读流
let rs = fs.createReadStream(__dirname + "/source/one.m4v");
(2) 监听open事件
// 2.监听读写流的打开
rs.once('open', () => {
console.log("读入流通道打开!");
});
(3) 监听data事件
// 3.监听读入数据
rs.on('data', (data) => {
console.log(data);
});
(4) 暂停和恢复
// 暂停
setTimeout(() => {
rs.pause();
}, 10);
// 恢复
setTimeout(() => {
rs.resume();
}, 2000);
3. 可写流createWriteStream
(1) 创建可写流
let ws = fs.createWriteStream(__dirname + "/target/five.m4v");
(2) write方法写入数据
ws.write(chunk,[encoding],[callback]);
rs.on('data', (data) => {
console.log(data);
ws.write(data);
});
4. pipe方法
pipe底层是对stream的封装
let fs = require('fs');
// 1.创建一个读流
let rs = fs.createReadStream(__dirname + "/source/one.m4v");
let ws = fs.createWriteStream(__dirname + "/target/six.m4v");
// 2.创建管道
rs.pipe(ws);