日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在前端開發中,開發者常常會使用文件上傳、下載或數據轉換的操作。JAVAScript 提供了許多 API 來處理二進制數據和轉換數據流,如:ArrayBuffer、FileReader、base64 、Blob、File等,他們之間的轉換與聯系如下所示。

 

Blob

Blob (binary large object) ,即二進制大對象,表示一個不可變、原始數據的類文件對象。它的數據可以按文本或二進制的格式進行讀取,在 web 網頁中的充當數據流使用的相當頻繁。

blob 對象上有兩個屬性:

  • size:Blob對象中所包含數據的大小(字節);
  • type:字符串,認為該Blob對象所包含的 MIME 類型。如果類型未知,則為空字符串。

 

let blob = new Blob([1,2,3,4,5], {type: "text/plAIn"});
// 可以 進行分割切片,如下
const _subBlob = blob.slice(0, 3,{type: "text/plain"});  // 此時切片的type 默認可以省略
URL.createObjectURL(blob);             //12345
URL.createObjectURL(_subBlob);     // 123

 

注意: 如果Blob的數據屬于Unicode 編碼中的 Supplementary Plane(輔助平面) 字符,也即是需要用兩個 16 位的 UTF-16 編碼單元(稱為代理對或代理字符)來表示,那么轉成的createObjectURL 鏈接不能獲取正確數據,獲得的是亂碼,此時可以使用FileReader進行獲取特定編碼格式的數據,如下:

let blob = new Blob(['!@#¥%']);
const _subBlob_o = blob.slice(0, 1);
const _subBlob_t = blob.slice(0, 2);
const _subBlob_th = blob.slice(0, 3);
URL.createObjectURL(_subBlob_o);      // ?
URL.createObjectURL(_subBlob_t);     // 錛
URL.createObjectURL(_subBlob_th);     // 錛?

// 以下使用 FileReader 獲取UTF-8類型的text文本數據
let blob = new Blob(['!¥%&*']);
let _subBlob_o = blob.slice(0,3);
let _subBlob_t = blob.slice(3,6);
let _subBlob_th = blob.slice(6,7);
let _subBlob_f = blob.slice(7,8);
let fileReader = new FileReader();

fileReader.onload = function(event) {
  let result = event.target.result;
  console.log(result); // 這里打印出讀取的數據,應該正確顯示UTF-8編碼的字節字符
};

// fileReader.readAsText(blob, 'UTF-8');              // output:   !(中文嘆號占用三個字節)
// fileReader.readAsText(_subBlob_o, 'UTF-8');   // output:   ¥(中文$占用三個字節)
// fileReader.readAsText(_subBlob_t, 'UTF-8');    // output:   %  
// fileReader.readAsText(_subBlob_th, 'UTF-8');  // output:   &

File

文件(File)Api 是一種用來描述有關文件信息的對象類型,File 對象本質上是繼承了 Blob 的一種封裝之后的對象 (包含 文件size、文件name和文件type) 。

File.__proto__ === Blob   // true

在web應用中可以通過 type為file的input標簽選擇文件后生成的 FileList 對象(這里獲取的是File的一個數組),也可以通過拖拽文件生成 DataTransfer 對象得到Filelist(通過 DataTransfer.files 獲取)。

File 對象都包含文件對象的一些屬性,這些屬性都繼承自 Blob 對象,根據MDN的解釋如下:

  • lastModified:引用文件最后修改日期,為自1970年1月1日0:00以來的毫秒數;
  • lastModifiedDate:引用文件的最后修改日期;
  • name:引用文件的文件名;
  • size:引用文件的文件大小;
  • type:文件的媒體類型(MIME);
  • webkitRelativePath:文件的路徑或 URL。

FileReader

FileReader 是一個在 JavaScript 中可以用來讀取文件內容的 API,它允許您讀取 Blob 或 File 對象中的數據,并將其轉換為其他格式,比如文本、二進制數據或數據 URL。

注意:FileReader 和 一些Blob、File操作,只能讀取文件不能修改文件,若想要直接寫入文件可以使用 a 標簽,指定轉成的文本,進行download,或者可以嘗試一下Chrome的實驗性的
window.chooseFileSystemEntries這個api獲取文件句柄操作(正式穩定版新版或沒有這個Api,了解即可)

  • downloadLink
const blob = new Blob(['{"name": "tong"}']);
const _link = document.createElement("a");
_link.download = 'e.json';
_link.href = URL.createObjectURL(blob);
_link.click();
  • chooseFileSystemEntries
// 文件句柄
let handle;
button.addEventListener('click', async (e) => {
  handle = await window.chooseFileSystemEntries();
});

1.FileReader 常用屬性:

  • error:表示在讀取文件時發生的錯誤;
  • result:文件內容。該屬性僅在讀取操作完成后才有效,數據的格式取決于使用哪個方法來啟動讀取操作。
  • readyState:表示 FileReader 狀態的數字。取值包含0(EMPTY)、1(LOADING)、2(DONE)

2.FileReader 常用 API(傳參是Blob或File):

  • readAsArrayBuffer():讀取數據,result 屬性中保存的將是被讀取文件的 ArrayBuffer 數據對象;
  • readAsBinaryString():讀取數據,result 屬性中將包含所讀取文件的原始二進制數據;
  • readAsDataURL():讀取數據,result 屬性中將包含一個dataURL 格式的 Base64 字符串以表示所讀取文件的內容。
  • readAsText():讀取數據,result 屬性中將包含一個字符串以表示所讀取的文件內容。

3. FileReader 常用 事件:

  • abort:該事件在讀取操作被中斷時觸發;
  • error:該事件在讀取操作發生錯誤時觸發;
  • load:該事件在讀取操作完成時觸發;
  • progress:該事件在讀取 Blob 時觸發。

input上傳事件,如下:

<input type="file" id="_input" />


const reader = new FileReader();

_input.onchange = (e) => {
  reader.readAsDataURL(e.target.files[0]);
};

reader.onload = (e) => {
  console.log(e.target.result);
};

ArrayBuffer

ArrayBuffer是 JavaScript 中用于表示一段二進制數據的對象。它是在 ECMAScript 6(ES2015)中引入的新類型,允許開發者以更直接的方式處理二進制數據,而無需依賴傳統的字符串和數組。它可以存儲各種數據類型的二進制數據,如整數、浮點數、字節等。ArrayBuffer 對象的大小在創建時確定,并且不能被改變,所以需要借助如下方式讀寫數據。

  • TypedArray:用來生成內存的視圖,通過9個構造函數,可以生成10種數據格式的視圖
Int8Array: 8 位有符號整數(-128 到 127)
Uint8Array: 8 位無符號整數(0 到 255)
Int16Array: 16 位有符號整數(-32,768 到 32,767)
Uint16Array: 16 位無符號整數(0 到 65,535)
Int32Array: 32 位有符號整數(-2^31 到 2^31-1)
Uint32Array: 32 位無符號整數(0 到 2^32-1)
Float32Array: 32 位浮點數(IEEE 754 標準的單精度浮點數)
Float64Array: 64 位浮點數(IEEE 754 標準的雙精度浮點數)
BigInt64Array: 64 位帶符號整數(-2^63 到 2^63-1)(在 ECMAScript 2020 中引入)
BigUint64Array: 64 位無符號整數(0 到 2^64-1)(在 ECMAScript 2020 中引入)
  • DataViews:用來生成內存的視圖,可以自定義格式和字節序。

包含三個參數:

buffer:一個已經存在的 ArrayBuffer 對象,DataView 對象的數據源。

byteOffset:可選,此 DataView 對象的第一個字節在 buffer 中的字節偏移。如果未指定,則默認從第一個字節開始。

byteLength:可選,此 DataView 對象的字節長度。如果未指定,這個視圖的長度將匹配 buffer 的長度。

 

對于ArrayBuffer的讀寫操作,具體如下:

const buffer = new ArrayBuffer(16); // 創建一個大小為 16 字節的 ArrayBuffer

// 使用DataView 讀寫 ArrayBuffer 數據
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);

view.setInt16(0, 42); // 在位置0寫入16位整數值42
view.setFloat32(2, 3.14); // 在位置2寫入32位浮點數值3.14

const value1 = view.getInt16(0); // 從位置0讀取16位整數值42
const value2 = view.getFloat32(2); // 從位置2讀取32位浮點數值3.14


// 使用 TypedArray 讀寫 ArrayBuffer 數據
const buffer = new ArrayBuffer(8);
const uint8Array = new Uint8Array(buffer);

// 使用 Uint8Array 來設置和獲取二進制數據
uint8Array[0] = 10;
uint8Array[1] = 20;
uint8Array[2] = 30;

console.log(uint8Array[0]); // 輸出 10
console.log(uint8Array[1]); // 輸出 20
console.log(uint8Array[2]); // 輸出 30

 

Object URL

Object URL(對象URL)是一個特殊的 URL 格式,用于臨時標識 JavaScript 中的 Blob、File 和 MediaSource 等二進制數據對象。通過創建 Object URL,您可以在瀏覽器中處理這些二進制數據,而無需直接暴露或嵌入這些數據。

Object URL 遵循以下格式:blob:<unique_id>,其中 <unique_id> 是一個唯一標識符,用于表示一個特定的二進制數據對象。這個 URL 可以被用于在客戶端(通常是在瀏覽器中)引用這些二進制數據,例如在 <img> 標簽的 src 屬性、<a> 標簽的 href 屬性、<video> 和 <audio> 標簽的 src 屬性等處。創建 Object URL 的常用方法是使用 URL.createObjectURL() 函數。該函數接受一個 Blob、File 或 MediaSource 對象作為參數,并返回一個 Object URL 字符串。這個 URL 字符串在 Blob 對象的生命周期內是有效的。

一般情況下,在以下情況下 Object URL 會被自動釋放:

  • 當相關的 JavaScript 代碼執行完成并不再引用 Object URL 時 (垃圾回收釋放)。
  • 當頁面被卸載(關閉或導航到其他頁面)時。
  • 當使用 URL.revokeObjectURL() 手動釋放 Object URL 時。

注意:在不需要使用URL時,應該通過 URL.revokeObjectURL() 函數來釋放它,以避免內存泄漏。如下:

   // 創建一個包含圖片數據的 Blob 對象
    const imageData = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10, /* ... */]);
    const blob = new Blob([imageData], { type: 'image/png' });

    // 創建 Object URL 并將圖片顯示在 <img> 標簽中
    const imageUrl = URL.createObjectURL(blob);
    const imageElement = document.getElementById('image');
    imageElement.src = imageUrl;

    // 在不需要 Object URL 時釋放它
    // 通常在不需要顯示圖片或其他二進制數據時調用
    // 這樣可以釋放瀏覽器內存,避免內存泄漏
    // 注意:在實際應用中,請根據需要選擇合適的時機來調用 URL.revokeObjectURL()
    // imageElement.onload = () => {
    //   URL.revokeObjectURL(imageUrl);
    // };

 

Base64

Base64 是一種編碼方式,它將二進制數據轉換成只包含 ASCII 字符的文本表示形式。這種編碼方式通常用于在文本協議中傳輸二進制數據,例如在電子郵件、URL、XML、JSON 等文本格式中嵌入圖片、音頻、視頻等二進制數據。Base64 編碼基于 64 個可打印的 ASCII 字符(A-Z,a-z,0-9,+ 和 /),以及一個用于填充的字符(通常是等號 =)。編碼規則如下:

  • 將 3 字節的二進制數據(24 位)劃分為四組,每組 6 位。
  • 將每組 6 位二進制數據轉換為一個可打印字符。
  • 如果原始數據不是 3 字節的倍數,則會在末尾添加一個或兩個等號(=)字符進行填充。

理論上說:Base64 編碼后的數據大小通常會比原始數據大約 33%,因為每 3 字節的數據會編碼成 4 個字符。會比blob url消耗更多內存,但是在不用的時候會自動從內存中清除(通過垃圾回收機制)。

在 JavaScript 中,可以使用 readAsDataURL api 和 canvas 的 toDataURL api 獲取 base64 格式的數據流。

注意:上述方式獲取的是一種根據數據類型生成的base64編碼數據,不是真實一一對應的base64編碼規則,因為添加了一些數據類型頭部,即:base64編碼的數據和 dataUrl 類型的數據不是一個東西。如。`data:image/jpeg;base64,/9j/`,這種的類型 (data: - Data URL 的協議頭部、image/jpeg - MIME 類型,表示數據的媒體類型、base64 - 表示數據是使用 Base64 編碼的。它告訴瀏覽器如何解碼數據、/9j/ - Base64 編碼后的數據的起始部分標識)。

想獲取完整標準的 Base64編碼,可以使用 btoa() 函數將字符串進行 Base64 編碼,以及使用 atob() 函數將 Base64 編碼的字符串解碼為原始字符串。在 Node.js 中,可以使用 Buffer.from() 和 Buffer.toString() 來進行 Base64 編碼和解碼。

  • atob(ascii to binary): 解碼 ,用于將ascii碼解析成binary數據。用于解碼Base64編碼的字符串。
  • btoa(binary to ascii):編碼,用于將binary數據用ascii碼表示。常用于編碼字符串。(不支持Unicode字符編碼),它的編碼范圍實際上是在 0 到 255 的整數值之間,即一個字節(8 位)的范圍。
const originalString = 'Hello, world!';
const encodedString = btoa(originalString);
const decodedString = atob(encodedString);

console.log(encodedString); // "SGVsbG8sIHdvcmxkIQ=="
console.log(decodedString); // "Hello, world!"

想要支持其他的Unicode字符編碼,可以使用以下方式:

  • 編碼時,先用encodeURIComponent對字符串進行編碼,再使用btoa進行編碼
  • 解碼時,先用atob對數據進行解碼 ,再用decodeURIComponent對字符串進行解碼
let str_unicode = "中國"
let encode_str_unicode =  btoa(encodeURIComponent(str_unicode));

console.log(encode_str_unicode);  //  JUU0JUI4JUFEJUU1JTlCJUJE
let decode_str_unicode = decodeURIComponent(atob(encode_str_unicode));
console.log(decode_str_unicode);  //  中國

注意: 上述的decodeURIComponent和encodeURIComponent是一種URI 編碼,一種將特殊字符轉換為可安全傳輸和顯示的形式的編碼方式。在 URI(Uniform Resource Identifier)中,某些字符被保留用于特殊用途,例如作為分隔符或標記符號。如果要在 URI 中包含這些保留字符,就需要將它們轉換為編碼形式,這樣才能正確傳輸和解析。比如我們常見到網頁路徑包含這種參數 `%E4%B8%AD%E5%9B%BD`

格式轉化

以下是一些常用的基本轉化:

1.Blob → ArrayBuffer

let blob = new Blob(['Hello,world'],{type: "text/plain"});
let fileReader = new FileReader();

fileReader.onload = function(event) {
  let result = event.target.result;
  console.log(result);  // ArrayBuffer(11)
};
fileReader.readAsArrayBuffer(blob, 'UTF-8');  

2.Blob → (Base64 | DataURL)

let blob = new Blob(['Hello,world'],{type: "text/plain"});
let fileReader = new FileReader();

fileReader.onload = function(event) {
  let result = event.target.result;
  console.log(result);   //  data:text/plain;base64,SGVsbG8sd29ybGQ=
  let arr = result.split(',');
	let bstr = atob(arr[1]) 
  console.log(bstr)  //   Hello,world
};
fileReader.readAsDataURL(blob, 'UTF-8');  

注意:以上的編碼依舊是不能支持所有Unicode編碼方式,因為blob中的數據有可能是一些高碼位的字符,那么readAsDataURL生成的dataurl有可能獲取的是亂碼,所以要給定blob生成時的字符編碼方式,此時處理方式如下:

const blob = new Blob([''], { type: 'text/plain;charset=UTF-8' }); // Specify UTF-8 encoding in the Blob
let fileReader = new FileReader();

fileReader.onload = function(event) {
  let result = event.target.result;
  console.log(result);   //  data:text/plain;charset=utf-8;base64,8KCcjg==
  let arr = result.split(',');
	let bstr = atob(arr[1]) 
// Convert binary string to UTF-8 string
const decoder = new TextDecoder('utf-8');
const utf8String = decoder.decode(new Uint8Array(bstr.length).map((_, i) => bstr.charCodeAt(i)));

console.log(utf8String); // ""
};
fileReader.readAsDataURL(blob, 'UTF-8');  

在上述示例中,我們首先使用 atob() 函數將 Base64 編碼的數據轉換為二進制數據(二進制字符串)。然后,我們使用 TextDecoder 對象將二進制數據轉換回原始的 UTF-8 字符串。

注意,TextDecoder 構造函數的參數 'utf-8' 指定了使用 UTF-8 編碼進行解碼。確保在解碼時使用與編碼時相同的字符編碼,以便正確還原原始數據。在我們之前的示例中,我們在創建 Data URL 時指定了 UTF-8 編碼,因此在解碼時也要使用 UTF-8 編碼。

3.Blob → Object URL

let blob = new Blob(['Hello,world']);
const objectUrl = URL.createObjectURL(blob); 

4.Blob → File

let blob = new Blob(['Hello,world']);
let file = new File([blob], "blob", {type: 'text/plain'})  // File{ name: "blob",size:11,type: "text/plain" ... }

5.ArrayBuffer → Blob

const buffer = new ArrayBuffer(12);
const s = new Uint8Array(buffer);
let u = [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100];
for (let i = 0; i < 12; i++) {
  s[i] = u[i]; 
}
const blob = new Blob([s]);
URL.createObjectURL(blob);    // Hello, World

6.ArrayBuffer → Base64

這里編碼方式有兩種,一種是可以通過btoa編碼的,即是上文所說的限制 255 以內的字符。另一種是兼容其他的Unicode碼點的轉換方式。(以下是演示需要,實際使用不需要創建其他多余的數據) 。

//(非高碼位)
const buffer = new ArrayBuffer(12);
const s = new Uint8Array(buffer);
let u = [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100];
for (let i = 0; i < 12; i++) {
  s[i] = u[i];
}
const base64 = btoa(String.fromCodePoint.Apply(null,s));
atob(base64)  // 'Hello, World'

// (高碼位)
const encoder = new TextEncoder();
const buffer = encoder.encode("").buffer;  // 這是在高碼位的一個字符
const s = new Uint8Array(buffer);     // 演示需要,轉成buffer

const  decoder = new TextDecoder();
const str = decoder.decode(buffer);
// console.log(str);  // ""  這里的輸出就是 想要的字符,以下的操作是為了演示Unicode也可以編碼。

// 編碼
let encode_str_unicode =  btoa(encodeURIComponent(str));
// 解碼
// let decode_str_unicode = decodeURIComponent(atob(encode_str_unicode));

console.log(encode_str_unicode);  //  JUYwJUEwJTlDJThF  這里的轉換得到的高碼位的編碼結果
// console.log(decode_str_unicode);  // ""

7. (Base64 | DataURL)→ Blob

const data_url =  "data:text/plain;charset=utf-8;base64,8KCcjg=="; // 這里是dataurl
let arr = data_url.split(',');
	let bstr = atob(arr[1])  // 這里就是base64 
// Convert binary string to UTF-8 string
const decoder = new TextDecoder('utf-8');
const utf8String = decoder.decode(new Uint8Array(bstr.length).map((_, i) => bstr.charCodeAt(i)));
console.log(utf8String); // "”
// 這里必須要給予charset 否則 createObjectURL生成的文本是亂碼
const blob = new Blob([utf8String], { type: 'text/plain;charset=UTF-8' });   
URL.createObjectURL(blob)  // 這里訪問即可得到   字符

總結: 關于數據流之間的關系以及如何轉換已經基本結束,其他的轉換也可以通過上述的數據轉換以及相關功能得到。關于數據流的一些想法和問題,可以評論區留言。

分享到:
標簽:JS
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定