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
- 486
 
   
   
  