Buffer的应用
一.编码的发展
一个字节由8个位组成,gbk中一个汉字2个字节,utf8中一个汉字3个字节
- ASCII编码
- GB2312
- GBK
- GB18030
- Unicode
- UTF-8
Node中不支持GBK编码,我们需要将GBK转为UTF8编码
var iconv = require('iconv-lite');
function readGBKText(pathname) {
var bin = fs.readFileSync(pathname);
return iconv.decode(bin, 'gbk');
}
1
2
3
4
5
2
3
4
5
二.进制转化
//把任意进制转成十进制
console.log(parseInt('20',10));//20
console.log(parseInt('11',2));//3
console.log(parseInt('20',16));//32
//把十进制转成任意进制
console.log((3).toString(2));//11
console.log(3..toString(2));//11
console.log((77).toString(8));//115
console.log((77).toString(16));//4d
console.log((17).toString(8));//21
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
三.Buffer的应用
1.定义buffer的三种方式
let buf1 = Buffer.alloc(6);
let buf2 = Buffer.from('珠峰');
let buf3 = Buffer.from([65,66,67]);
1
2
3
2
3
2.buffer中常用的方法
- buff.toString()
- buff.fill()
- buff.slice()
- buff.copy
- Buffer.concat()
- Buffer.isBuffer()
- indexOf
copy方法的实现
Buffer.prototype.copy = function(targetBuffer,targetStart,sourceStart,sourceEnd){
for(let i=sourceStart;i<sourceEnd;i++){
targetBuffer[targetStart++]=this[i];
}
}
1
2
3
4
5
2
3
4
5
concat方法的实现
Buffer.concat = function(bufferList,len=bufferList.reduce((a,b)=>a+b.length,0)){
let buffer = Buffer.alloc(len);
let offset = 0;
bufferList.forEach(buf=>{
buf.copy(buffer,offset);
offset += buf.length;
})
return buffer;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
封装buffer.split方法
Buffer.prototype.split = function(sep){ // slice + indexOf = split
let arr = [];
let len = Buffer.from(sep).length; // 分割符号的长度
let offset = 0;
let current;
while(-1!=(current = this.indexOf(sep,offset))){
// 找到的位置 加上偏移量
arr.push(this.slice(offset,current));
offset = current+len;
}
arr.push(this.slice(offset));
return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
3.base64转化
const CHARTS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function transfer(str){
let buf = Buffer.from(str);
let result = '';
for(let b of buf){
result += b.toString(2);
}
return result.match(/(\d{6})/g).map(val=>parseInt(val,2)).map(val=>CHARTS[val]).join('');
}
let r = transfer('a');
console.log(r);
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
四.前端二进制对象
前端最常用的Blob对象 binary large object (是不可变的) 代表的是文件类型
1.前端下载html功能
let str = `<h1>hello world</h1>`;
const blob = new Blob([str], {
type: 'text/html'
});
let a = document.createElement('a');
a.setAttribute('download', 'a.html');
a.href = URL.createObjectURL(blob);
document.body.appendChild(a);
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
2.前端文件预览
使用fileReader来实现
file.addEventListener('change', (e) => {
let file = e.target.files[0];
let fileReader = new FileReader();
fileReader.onload = function () {
let img = document.createElement('img');
img.src = fileReader.result;
document.body.appendChild(img)
}
fileReader.readAsDataURL(file);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
createObjectURL来实现
let r = URL.createObjectURL(file);
let img = document.createElement('img');
img.src = r;
document.body.appendChild(img)
URL.revokeObjectURL(r);
1
2
3
4
5
2
3
4
5
3.arrayBuffer(浏览器中的二进制)
let buffer = new ArrayBuffer(4);// 创造4个字节
let x1 = new Uint8Array(buffer);
x1[0] = 1; // 00000000 00000000 11111111 00000001
x1[1] = 255;
console.log(x1); // [1,255,0,0]
let x2 = new Uint16Array(buffer);
console.log(x2) // [65281,0]
let x3 = new Uint32Array(buffer);
console.log(x3) // [65281]
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
arraybuffer不能被直接修改
4.字符串和arrayBuffer转化
字符串转化成arrayBuffer
function stringToArrayBuffer(str) { // utf16 不管是字符还是汉字
let buffer = new ArrayBuffer(str.length * 2);
let view = new Uint16Array(buffer)
for (let i = 0; i < str.length; i++) {
view[i] = str.charCodeAt(i)
}
return buffer
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
arrayBuffer转化成字符串
function ArrayBufferToString(buf) {
return String.fromCharCode(...new Uint16Array(buf))
}
1
2
3
2
3
5.responseType:'arrayBuffer'
function request(url, method = "get") {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
resolve(xhr.response);
}
xhr.send();
})
}
request('/download').then(arraybuffer => {
let b = new Blob([arraybuffer]);
let blobUrl = URL.createObjectURL(b);
let a = document.createElement('a');
a.href = blobUrl;
a.download = 'a.pdf';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(blobUrl)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
服务端代码
const express = require('express');
const app = express();
app.listen(4444);
app.use(express.static(__dirname));
app.get('/download', (req, res) => {
res.download('a.pdf');
})
1
2
3
4
5
6
7
2
3
4
5
6
7