Buffer và Encoding trong Node.js

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 31 tháng 1, 2025

Trong Node.js, Buffer là một đối tượng dùng để làm việc với dữ liệu nhị phân (binary data). Nó hữu ích khi xử lý file, stream, hoặc dữ liệu từ mạng, đặc biệt là khi Node.js không có sẵn kiểu dữ liệu nhị phân như trong các ngôn ngữ khác như C hoặc Java.

1. Khái niệm Buffer trong Node.js

Tại sao cần Buffer?

  • JavaScript thuần chỉ hỗ trợ chuỗi (string), không có kiểu dữ liệu nhị phân.
  • Khi làm việc với dữ liệu nhị phân như hình ảnh, âm thanh, video, hoặc stream, cần một cách để xử lý dữ liệu dưới dạng mảng byte.
  • Buffer giúp lưu trữ dữ liệu nhị phân và hoạt động giống như một mảng byte nhưng hiệu quả hơn.

2. Tạo Buffer trong Node.js

Có nhiều cách để tạo Buffer trong Node.js:

Cách 1: Sử dụng Buffer.from()

const buf = Buffer.from("Hello", "utf-8");
console.log(buf); // <Buffer 48 65 6c 6c 6f>

Giải thích:

  • "Hello" được mã hóa thành mã hex (48 65 6c 6c 6f).
  • Mặc định, Buffer.from() dùng mã hóa "utf-8", nhưng có thể chỉ định ascii, base64, v.v.

Cách 2: Sử dụng Buffer.alloc() để tạo Buffer có độ dài cố định

const buf = Buffer.alloc(10); // Tạo Buffer 10 byte, tất cả giá trị mặc định là 0
console.log(buf); // <Buffer 00 00 00 00 00 00 00 00 00 00>

Lưu ý:

  • Buffer.alloc(size) giúp tạo một buffer an toàn, khởi tạo tất cả byte về 0.

Cách 3: Sử dụng Buffer.allocUnsafe() (không khởi tạo dữ liệu, nhanh hơn nhưng có thể chứa dữ liệu rác)

const buf = Buffer.allocUnsafe(10); // Tạo Buffer 10 byte mà không khởi tạo
console.log(buf); // Có thể chứa dữ liệu ngẫu nhiên

Lưu ý:

  • allocUnsafe() nhanh hơn alloc(), nhưng có thể chứa dữ liệu cũ trong bộ nhớ.
  • Nếu cần dữ liệu rỗng, hãy dùng alloc().

3. Chuyển đổi dữ liệu với Buffer

Chuyển Buffer thành chuỗi

const buf = Buffer.from("Hello");
console.log(buf.toString());      // "Hello"
console.log(buf.toString("hex")); // "48656c6c6f"
console.log(buf.toString("base64")); // "SGVsbG8="

Giải thích:

  • toString() chuyển Buffer thành chuỗi với mã hóa utf-8.
  • toString("hex") chuyển thành mã hex.
  • toString("base64") chuyển thành mã base64 (dùng phổ biến trong mã hóa dữ liệu).

Chuyển đổi từ Buffer sang JSON

const buf = Buffer.from("Hello");
const json = buf.toJSON();
console.log(json);

Kết quả:

{ "type": "Buffer", "data": [72, 101, 108, 108, 111] }

Giải thích:

  • toJSON() chuyển Buffer thành mảng byte JSON.
  • Mỗi phần tử trong data là một byte của chuỗi "Hello".

So sánh và nối Buffer

So sánh hai Buffer

const buf1 = Buffer.from("abc");
const buf2 = Buffer.from("abc");
const buf3 = Buffer.from("xyz");

console.log(buf1.equals(buf2)); // true
console.log(buf1.equals(buf3)); // false
  • equals() kiểm tra hai Buffer có giống nhau không.

Nối nhiều Buffer với Buffer.concat()

const buf1 = Buffer.from("Hello ");
const buf2 = Buffer.from("World");
const buf3 = Buffer.concat([buf1, buf2]);

console.log(buf3.toString()); // "Hello World"
  • Buffer.concat() giúp nối nhiều Buffer thành một Buffer mới.

4. Ghi dữ liệu vào Buffer

const buf = Buffer.alloc(10);
buf.write("Hello");

console.log(buf.toString()); // "Hello"

Giải thích:

  • write() ghi dữ liệu vào Buffer.

5. Đọc và ghi từng byte trong Buffer

const buf = Buffer.from([72, 101, 108, 108, 111]);
console.log(buf[0]); // 72 (chữ 'H')

buf[0] = 74; // Thay đổi giá trị byte đầu tiên thành 74 ('J')
console.log(buf.toString()); // "Jello"

Giải thích:

  • Buffer hoạt động giống như một mảng byte, có thể truy cập từng phần tử bằng chỉ số.

6. Encoding – Các kiểu mã hóa dữ liệu

Node.js hỗ trợ nhiều kiểu mã hóa khi làm việc với Buffer:

Mã hóa Mô tả
utf-8 Mặc định, dùng phổ biến cho văn bản.
ascii Chỉ hỗ trợ 128 ký tự ASCII đầu tiên.
base64 Dùng trong mã hóa dữ liệu, đặc biệt là truyền file nhị phân.
hex Biểu diễn dữ liệu dưới dạng chuỗi hex.
latin1 Hỗ trợ ký tự Latin-1.

Ví dụ về Base64 Encoding

const buf = Buffer.from("Hello, world!");
const base64Str = buf.toString("base64");

console.log(base64Str); // "SGVsbG8sIHdvcmxkIQ=="
  • Ứng dụng thực tế: Base64 thường được dùng để mã hóa hình ảnh hoặc dữ liệu nhị phân để lưu vào cơ sở dữ liệu hoặc gửi qua mạng.

7. Ứng dụng thực tế của Buffer

Đọc file nhị phân (hình ảnh) bằng Buffer

const fs = require("fs");

fs.readFile("image.png", (err, data) => {
  if (err) throw err;
  console.log(data); // Buffer chứa dữ liệu ảnh
});
  • fs.readFile() trả về dữ liệu dưới dạng Buffer khi đọc file nhị phân.

8. Tổng kết

Chức năng Mô tả
Tạo Buffer Buffer.from(), Buffer.alloc(), Buffer.allocUnsafe()
Chuyển đổi dữ liệu .toString(), .toJSON(), .write()
So sánh Buffer .equals(), .compare()
Nối Buffer Buffer.concat()
Truy cập byte buf[index]
Mã hóa utf-8, hex, base64

Buffer là một phần quan trọng trong Node.js giúp xử lý dữ liệu nhị phân một cách hiệu quả, đặc biệt khi làm việc với file, stream, hoặc dữ liệu mạng.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ