# Blob ###### tags: `讀書會` ## What is BLOB - 字面上:Binary Big Object - 概念上:array of bytes - JS 實務上:`Blob` 物件,有 size 和 type ## `Blob` object in javascropt: - 和檔案一樣,有自己的檔案大小和 MIME 格式。使用上,和使用檔案一樣。 - 建立後內容無法修改 - 可以透過 `URL.createObjectURL` 建立存取 Blob 的 URI ### size ```javascript= var htmlFragment = '<p>你好</p>'; var htmlBlob = new Blob([htmlFragment], { type: 'text/html' }); // Blob {size: 13, type: 'text/html'} // 13 is how many bytes of the string '<p>你好</p>' ``` ```javascript= var jsonData = JSON.stringify({ hello: 'world' }, null, 2); // '{\n "hello": "world"\n}' var jsonData2 = JSON.stringify({ hello: 'world' }); // '{"hello":"world"}' var jsonBlob = new Blob([jsonData], { type: 'application/json' }); // {size: 22, type: 'application/json'} var jsonBlob2 = new Blob([jsonData2], { type: 'application/json' }); // {size: 17, type:'application/json'} var jsonBlob3 = new Blob([jsonBlob]); // {size: 22, type: ''} ``` ### Create a unique url from a blob object ```javascript= url = window.URL.createObjectURL(jsonBlob); // 'blob:https://pjchender.dev/7325eb6c-ba5a-42b1-8f78-ced5fcb7be8e' // release the memory of the url window.URL.revokeObjectURL(url); ``` ## Example Create file on client side. For [example](https://www.youtube.com/watch?v=_HZdLuGL8Ho), make a CSV file to be download ```javascript= const data = [ ['Id', 'Name', 'Age'], [1, 'Bob', 20], [2, 'Amy', 12], [3, 'Joe', 30], [4, 'Foo', 55] ] const makeCSV = () => { const str = data.map(row => row.join(",")).join("\n"); console.log(str); return new Blob([str]); } const makeDownloadButton = () => { const a = document.createElement('a'); document.body.appendChild(a); // 將 blob 放到 URL 上 const blob = makeCSV(); url = window.URL.createObjectURL(blob); a.href = url; a.text = 'Download CSV'; a.download = 'demo.csv'; } makeDownloadButton(); ``` # Dive deeper: Buffer & View ### 概念上: - A Blob can convert to a buffer. A buffer can make a blob. - Buffer 是一個指向儲存資料的記憶體區塊之物件,無法直接存取或修改 buffer 內部的資料。操作資料需要透過 View ### JS 實務上: - `ArrayBuffer`:Buffer,代表一段記憶體區塊,僅能透過 View 操作其內容。 - `TypedArray`:View,儲存固定型別資料的 Array,例如 Uint8Array(8-bit unsigned integer)、Float64Array(64-bit IEEE floating point number)。 - `DataView`:View,不限制型別,可自定義從哪個 byte,以什麼型別,用哪種 byte order(endian)存取。 ```javascript= const buffer = new ArrayBuffer(2); const bytes = new Uint8Array(buffer); // view // modify data through view bytes[0] = 65; bytes[1] = 66; const blob = new Blob([buffer], { type: 'text/plain' }); const dataUri = window.URL.createObjectURL(blob); window.open(dataUri); ``` 所謂的 Typed,意指「限定型別」,Array 中的元素都是同一種型別。 TypedArray 本身並並不儲存任何 buffer 資料,只保存該 buffer 的 reference ## Examples ### C struct 當需處理類似 C struct 的複合資料結構,如下所示 ``` struct employee { unsigned int id; // 4 * 1 bytes unsigned char department[4]; // 1 * 4 bytes float salary; // 4 * 1 bytes }; ``` <!-- ![](https://i.imgur.com/U7L0DOM.png) --> ![](https://i.imgur.com/n2TCegW.png) 我們可以宣告對應的 TypedArray 來處理。模擬出 C struct 的資料結構。 ``` const buffer = new ArrayBuffer(12) const idView = new Uint32Array(buffer, 0, 1) const deptView = new Uint8Array(buffer, 4, 4) const salaryView = new Float32Array(buffer, 8) idView[0] = 123 deptView.forEach((_, i) => { deptView[i] = i * i }) salaryView[0] = 10000 ``` ### Image <!-- [image in memory] --> ![](https://i.imgur.com/dKEYYZ7.png) 32-bits per pixcel generally means 4 channels (RGBA) per pixel. depth of each channel is 8-bits (0 ~ 255) # Recap - Blob - 字面上:Binary Big Object - 概念上:array of bytes - JS 實務上:`Blob` 物件,有 size 和 type - 應用 - Generate downloadable file URI at client side <!-- - Blob is representation of a chunk of bytes. Web Browsers implement a `Blob` object, which is responsible for holding data. - A Blob has its size and MIME type just like a file has - Most APIs for working with blobs are asynchronous. - Blob is immutable, ArrayBuffer can be mutated by View - Blob URI is a pointer to a memory --> ## Reference - https://pjchender.dev/webapis/webapis-blob-file/ - https://blog.techbridge.cc/2017/09/24/binary-data-manipulations-in-javascript/ - https://github.com/noahunallar/arraybuffer-vs-blob - https://javascript.plainenglish.io/javascript-blob-why-is-it-useful-20c372dfca00 - https://morosedog.gitlab.io/nodejs-20200123-Nodejs-11/