---
# System prepended metadata

title: Blob
tags: [讀書會]

---

# 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/
