ArrayBuffer
對象、TypedArray
視圖和DataView
視圖是 JavaScript 操作二進制數據的一個接口。它們都是以數組的語法處理二進制數據,所以統稱爲二進制數組。
二進制數組由三類對象組成。
(1)ArrayBuffer
對象:
代表內存之中的一段二進制數據,可以通過“視圖”進行操作。“視圖”部署了數組接口,這意味着,可以用數組的方法操作內存。
(2)TypedArray
視圖:
共包括 9 種類型的視圖,比如Uint8Array
(無符號 8 位整數)數組視圖, Int16Array
(16 位整數)數組視圖, Float32Array
(32 位浮點數)數組視圖等等。
(3)DataView
視圖:
可以自定義複合格式的視圖,比如第一個字節是 Uint8(無符號 8 位整數)、第二、三個字節是 Int16(16 位整數)、第四個字節開始是 Float32(32 位浮點數)等等,此外還可以自定義字節序。
簡單說,ArrayBuffer
對象代表原始的二進制數據,TypedArray
視圖用來讀寫簡單類型的二進制數據,DataView
視圖用來讀寫複雜類型的二進制數據。
TypedArray
視圖支持的數據類型一共有 9 種(DataView
視圖支持除Uint8C
以外的其他 8 種)。
一、arrayBuffer和new Blob
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="file" id="file"/>
<script>
/* //上傳文件 後端返回的是buffer 前端操作excel
// 前端最常用的是Blob對象() binary large object 是不可變的。
// File 基於Blob的。
// 1.實現前端下載html。
let str='<h1>hello world</h1>';
const blob=new Blob([str],{
type:'text/html'
})
// 前端下載用a標籤。
// 通過blob產生一個臨時訪問的鏈接
let a=document.createElement('a');
a.innerHTML='下載';
a.setAttribute('download','a.html');
a.href=URL.createObjectURL(blob);
document.body.appendChild(a); */
// 通過字符串構建一個blob。
//2) webgl
// 二進制類型 不能直接修改arrayBuffer。
// Blob 是傳輸的整體文件。
let arrayBuffer=new ArrayBuffer(10);
console.log(arrayBuffer);
let blob=new Blob([arrayBuffer]);
console.log(blob);
// blob 代表的是傳輸的整體文件。
// FileReader 文件讀取器。
let fileReader=new FileReader();
fileReader.οnlοad=function (){
console.log(fileReader.result);
}
// 儘量使用createObjectURL(blob) 來產生url。
fileReader.readAsDataURL(blob); // 轉化成base64
// fileReader 預覽功能。
// file 核心就是一個blob 只是在這個基礎上做了擴展。
file.addEventListener('change',(e)=>{
//1) 第一種方案
let file=e.target.files[0];
let fileReader=new FileReader();
fileReader.οnlοad=function (){
let img=document.createElement('img');
img.src=fileReader.result;
document.body.appendChild(img);
}
// 儘量使用createObjectURL(blob) 來產生url。
fileReader.readAsDataURL(file); // 轉化成base64
// 2)第二種方案
// 一般選擇下面的方案。
/* let r=URL.createObjectURL(file);
console.log(r);
let img=document.createElement('img');
img.src=r;
document.body.appendChild(img); */
//URL.revokeObjectURL(r); // 釋放掉URL
})
// arrayBuffer 瀏覽器中的二進制
// 通過視圖來進行訪問。
let buffer =new ArrayBuffer(4) //創造4個字節。
// TypeArray 描述底層的二進制數據。 int8Array uint8Array
// TypeArray 對象描述了一個底層的二進制數據緩衝區 的類視圖。
let x1=new Uint8Array(buffer);
x1[0]=1;
console.log(x1);
let x2=new Uint16Array(buffer);
// DateView 也可以通過一個接口去改
// buffer 是表示內存的。
// 如果將字符串轉化成arrayBuffer(前端) == buffer (後端)
function stringToArrayBuffer(str){ //後端3個字節。 前端用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;
}
console.log(ArrayBufferToString(stringToArrayBuffer('你好')))
// arrayBuffer 沒有toString的方法。
function ArrayBufferToString(buf){
return String.fromCharCode(...new Uint16Array(buf));
}
//前端解析excel
// 發送一個請求,服務端返回一個文件 實現下載即可。
function request(url,method='get'){
return new Promise((resolve,reject)=>{
let xhr=new XMLHttpRequest();
xhr.open(method,url,true);
xhr.responseType="arraybuffer";
xhr.οnlοad=function(){
resolve(xhr.response);
}
xhr.send();
})
}
request('/download').then(arraybuffer=>{
let b=new Blob([arraybuffer]); //直接將arrayBuffer封裝成文件。
console.log(b);
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);
})
</script>
</body>
</html>
二、Buffer的使用
/**
* 1、三種聲明方式 代表的是內存 大小是不能發生變化的。
* 2、buffer 可以通過數字 通過字符串 通過數組 來聲明,都是固定大小的
*
* 3、常用的聲明:長度和內容來聲明。
*/
let buffer=Buffer.alloc(10);
console.log(buffer);
// 16進制 最大就是ff
let buffer1=Buffer.from('數據'); // uft8 一個漢字是有3個字節組成。
console.log(buffer1.toString('base64'));
let buffer2=Buffer.from([0xe6,0x95,0xb0]);
console.log(buffer2);
// Buffer 可以和字符串任意的轉化
// 怎麼轉化base 64
// base64 以前是6個 現在是8個。 可以放到任何url的地方,不能轉化大圖片。
// base64 核心:編碼操作, 1個漢字3個字節 24位===> 4x6的格式.
let code=Buffer.from('數');
console.log(0xe6.toString(2),0x95.toString(2),0xb0.toString(2)); //0xe6 0x95 0xb0
// 00111001 00101001 00010110 00110000
// 取值範圍 0-63 所以只能叫base64
// 取值表。
let str='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
str+='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.toLowerCase();
str+='0123456789+/';
console.log(parseInt('00111001',2));
console.log(parseInt('00101001',2));
console.log(parseInt('00010110',2));
console.log(parseInt('00110000',2));
console.log(str[57]+str[41]+str[22]+str[48]);
// 前端的二進制
三、編碼問題
## 編碼問題
- ASCII 編碼 目前定義了128個字符。
- 一個字節多少位 8位 位裏面存的是二進制。二進制逢二進一
- parseInt('1011',2); // 二進制
- 0xff 16進制的 255
- 兩個字節來表示一個漢字 GB2312 兩個字節用來表示中文
- 255*255 = 65025
- GBK 融入了一些生僻漢字
- GB18030 融入了少數字符集
- unicode 只是一個字符集而已 做了一個編碼 100多萬個字符
- unf8 是unicode 的一種存儲方式。可變字符長度 字母1個字節 漢字3個字節
- uft16 / ucs-2 js內部就是使用的utf-8 兩個字節表示一個字符 不管是字母還是漢字。
- node中默認只支持uft-8格式的。
- 任意進制轉化爲10進制 parseInt()
- 10 進制轉化爲其他進制 toString();
## buffer
- 後端操作數據(二進制類型) buffer就是用來表示這些二進制
- fs.readFile(); (默認操作文件) 都是二進制類型。buffer他是16進制的。