# 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
};
```
<!--  -->

我們可以宣告對應的 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] -->

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/