node Buffer 學習

江小魚發表於2018-06-09

Buffer

  • node 中操作檔案都是二進位制
  • 宣告一段記憶體
    • Buffer.from() 宣告陣列或者字串
    • Buffer.alloc() 宣告長度 安全 速度慢
    • Buffer.allocUnsafe() 宣告長度 不安全 速度快
  • 二進位制特點: 長
  • buffer 中把二進位制轉成16進位制展示
  • 分配記憶體大小不能更改
  • 引用型別,很像二維陣列

buffer 的宣告

  • 通過長度建立
let buffer = Buffer.alloc(3);
console.log(buffer);
// <Buffer 00 00 00>
複製程式碼
  • 通過陣列建立 0 - 255
let buffer = Buffer.from([1,2,3]);

console.log(buffer);
複製程式碼
  • 用字串建立(node 不支援gb2312)
let buffer = Buffer.from('小魚兒');

console.log(buffer);
// <Buffer e5 b0 8f e9 b1 bc e5 84 bf>
複製程式碼
  • 編碼轉化
// 編碼轉化
npm install -D iconv-lite

// 轉化編碼
let iconvLite = require('iconv-lite');
let fs = require('fs');
let path = require('path');

let r = fs.readFileSync(path.resolve(__dirname, 'a.text'));
let result = iconvLite.decode(r, 'gbk');
console.log(result);
複製程式碼
  • buffer 可以和字串進行轉化
let buffer = Buffer.from('小魚');
console.log(buffer.slice(0, 3).toString());

複製程式碼

注意:如果不能拼成漢字,需要對不能輸出的進行快取,等可以拼成漢字後在輸出

let buffer = Buffer.from('小魚');
console.log(buffer.slice(0, 2).toString());
console.log(buffer.slice(2, 6).toString());
// 會有亂碼
複製程式碼

快取輸出

let { StringDecoder } = require('string_decoder');
let buffer = Buffer.from('小魚');
let a = buffer.slice(0, 2);
let b = buffer.slice(2, 6);
let sd = new StringDecoder();
console.log(sd.write(a)); // 輸出空 此時不是正常漢字,儲存在sd內部
console.log(sd.write(b)); // 小魚  將快取一起輸出
複製程式碼
  • Buffer.copy()
let buffer1 = Buffer.alloc(6);
let buffer2 = Buffer.from('小魚');
// for (let i = 0; i < buffer2.length; i++) {
//   buffer1[i] = buffer2[i];
// }
//      目標  目標開始  源開始 源結束 
buffer2.copy(buffer1, 0, 0, 6);
console.log(buffer1.toString());
// 小魚
複製程式碼

實現 copy

Buffer.prototype.myCopy = function(target, targetStart, sourceStart, sourceEnd) {
  for (let i = 0; i < sourceEnd - sourceStart; i++) {
    target[i + targetStart] = this[sourceStart + i]
  }
}
let buffer1 = Buffer.alloc(6);
let buffer2 = Buffer.from('小魚');
buffer2.myCopy(buffer1, 3, 3, 6);
console.log(buffer1.toString());
複製程式碼
  • Buffer.concat()
let buffer1 = Buffer.from('小');
let buffer2 = Buffer.from('魚');

Buffer.concat = function(list, len) {
  // 對list 求和 拷貝後的長度
  if (typeof len === 'undefined') {
    len = list.reduce((current, next, index) => {
      return current + next.length;
    }, 0);
  }
  let newBuffer = Buffer.alloc(len);
  // 這是拷貝開始
  let index = 0;
  // 對 buffer 進行拷貝
  list.forEach(buffer => {
    buffer.copy(newBuffer, index);
    index += buffer.length;
  });
  return newBuffer.slice(0, index);
}
console.log(Buffer.concat([buffer1, buffer2], 10).toString());
複製程式碼
  • buffer.indexOf()
let b = Buffer.from([1,2,3,4]);
console.log(b.indexOf(3)); // 2
console.log(b.indexOf(10)); // -1
複製程式碼

小需求:實現分割 split 方法

Buffer.prototype.split = function(sep) {
  // 先找到 分隔符的索引
  let index = 0;
  // 將分隔符轉化成buffer 獲取長度
  let len = Buffer.from(sep).length;
  let i = 0;
  let arr = [];
  while ((i = this.indexOf(sep, index)) !== -1) {
    let a = this.slice(index, i);
    arr.push(a);
    // 修改 分隔符位置
    index = i + len;
  }
  // 將最後一個也放到陣列中
  arr.push(this.slice(index));
  return arr.map(item => item.toString());
}
let buffer = Buffer.from('小魚**小魚**小魚');

let arr = buffer.split('**');
console.log(arr);
// [ '小魚', '小魚', '小魚' ]
複製程式碼

相關文章