Buffer && View
又要報告ㄖ,該報告什麼呢QQ
機智的我決定來逛逛 NTCH
哦哦一年前的我寫的但沒很懂只是把 這篇 的說明步驟做一做而且最後其實算是小白寫出來的
重新研究了一下
覺得這可以喔
Why we need Buffer && View ?
Defination
Buffer: It represents a fixed-size chunk of contagious memory (binary data), can't directly access or modify
View: Interpreting binary data in Buffer from different perspectives, the way we manipulate Buffer
In ES6
Buffer: ArrayBuffer
View:
// Allocate 2 bytes, the initial value is 0
const buffer = new ArrayBuffer(2)
// 00000000 00000000
- TypedArray (Uint8Array, Uint16Array......)
- DataView
const u8 = new Uint8Array(2)
// 00000000 00000000
// => Uint8Array(2) [0, 0]
8 bit = 1 byte
View:
- TypedArray (Uint8Array, Float64Array......)
- DataView
const u8 = new Uint8Array(2)
// 00000000 00000000
// => Uint8Array(2) [0, 0]
On the data of ArrayBuffer, set up a layer of Array API that can access the data
View:
- TypedArray (Uint8Array, Float64Array......)
- DataView
const u8 = new Uint8Array(2)
// 00000000 00000000
// => Uint8Array(2) [0, 0]
const u8 = new Uint8Array(2)
// 00000000 00000000 -> 8 bits a count
// => Uint8Array(2) [0, 0]
const u16 = new Uint16Array(u8.buffer)
// 0000000000000000 -> 16 bits a count
// => Uint16Array(2) [0]
We can decide how to read the binary data by different TypeArray
If Overflow......
Discard overflowing high bits
Uint8ClampedArray
Uint8Array.of(0xff, 0x100)
// Unit8Array [255, 0]
Uint8Array.of(0xff, 0x100, -100)
// Unit8Array [255, 0, 156]
Uint8ClampedArray.of(0xff, 0x100, -100)
// Uint8ClampedArray [255, 255, 0]
Why we need Buffer && View ?
Why we need Buffer && View ?
Manipulate Binary Data
Why don't we use Array ?
Array
ArrayBuffer
contain types
binary
number, string, array......
memory-use
fixed-size
dynamic
ArrayBuffer take less space when the exact data format is known, allows you to move more exactly through your data and gives the compiler/interpreter greater options for optimization.
Why don't we use Array ?
Use Case
- WebGL
- Canvas
- Fetch API
- FILE API
- WebSockets
- XMLHttpRequest
function getFileMagicNumber(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onerror = reject;
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce((accumBytes, byte) => [...accumBytes, byte.toString(16).padStart(2, '0')], [])
.join('')
.toUpperCase();
resolve(bytes);
};
});
}
function getFileMagicNumber(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onerror = reject;
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce((accumBytes, byte) => [...accumBytes, byte.toString(16).padStart(2, '0')], [])
.join('')
.toUpperCase();
resolve(bytes);
};
});
}
check MIME type
use the FileReader to read the first four bytes of a file to determine the MIME type of the file.
// fileTypes.js
export const IMAGE_PNG = '89504E47';
export const IMAGE_GIF = '47494638';
export const APPLICATION_PDF = '25504446';
....
Hex signature (wiki)
function getFileMagicNumber(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onerror = reject;
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce((accumByte, byte) => [...accumByte, byte.toString(16).padStart(2, '0')], [])
.join('')
.toUpperCase();
resolve(bytes);
};
});
}
check MIME type
use the FileReader to read the first four bytes of a file to determine the MIME type of the file.
// fileTypes.js
export const IMAGE_PNG = '89504E47';
export const IMAGE_GIF = '47494638';
export const APPLICATION_PDF = '25504446';
....
export default function checkFileTypes(file, allowTypes = []) {
return new Promise(async (resolve, reject) => {
const magicNumber = await getFileMagicNumber(file);
if (!~allowTypes.flat().indexOf(magicNumber)) {
reject(new Error('Invalid File Type'));
}
resolve();
});
}
function getFileMagicNumber(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onerror = reject;
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce(
(accumBytes, byte) => [...accumBytes, byte.toString(16).padStart(2, '0')]
, [])
.join('')
.toUpperCase();
resolve(bytes);
};
});
}
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce(
(accumBytes, byte) => [...accumBytes, byte.toString(16).padStart(2, '0')]
, [])
.join('')
.toUpperCase();
resolve(bytes);
};
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce(
(accumBytes, byte) => [...accumBytes, byte.toString(16).padStart(2, '0')]
, [])
.join('')
.toUpperCase();
resolve(bytes);
};
odd number of bytes
Why can't I use other TypedArray🤔
reader.onload = () => {
const uintArray = new Uint8Array(reader.result);
const bytes = uintArray
.slice(0, 4)
.reduce(
(accumBytes, byte) => [...accumBytes, byte.toString(16).padStart(2, '0')]
, [])
.join('')
.toUpperCase();
resolve(bytes);
};
cause Array can contain String
TypedArray
hexadecimal
[137, 80. 78, 71] base 10
[89, 50, 4e, 29] base 16
one more thing
可4下下禮拜又我 算惹
- ASCII, UTF8, UTF16, UTF32
- Endianness
- TypedArray && DataView
Buffer and View
By Jay Chou
Buffer and View
- 292