1. Analisis pembukaan
Buffer buffer yang disebut berarti "area penyimpanan sementara", yang merupakan bagian dari memori yang sementara menyimpan data input dan output.
Bahasa JS itu sendiri hanya memiliki tipe data string dan tidak ada tipe data biner. Oleh karena itu, NodeJS menyediakan buffer konstruktor global yang peer to string untuk menyediakan operasi pada data biner. Selain membaca file untuk mendapatkan instance buffer, itu juga dapat dibangun secara langsung, misalnya:
Salinan kode adalah sebagai berikut:
var buffer = buffer baru ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
Buffer mirip dengan string. Selain menggunakan atribut .length untuk mendapatkan panjang byte, Anda juga dapat menggunakan metode [indeks] untuk membaca byte pada posisi yang ditentukan, misalnya:
Salinan kode adalah sebagai berikut:
buffer [0]; // 0x68;
Buffer dan string dapat dikonversi satu sama lain, misalnya, data biner dapat dikonversi ke string menggunakan pengkodean yang ditentukan:
Salinan kode adalah sebagai berikut:
var str = buffer.toString ("UTF-8"); // Halo
Mengubah string ke data biner di bawah pengkodean yang ditentukan:
Salinan kode adalah sebagai berikut:
var buffer = buffer baru ("halo", "UTF-8"); // <buffer 68 65 6c 6c 6f>
Sedikit perbedaan:
Ada perbedaan penting antara buffer dan string. String hanya baca, dan modifikasi apa pun pada string menghasilkan string baru, dan string asli tetap tidak berubah.
Sedangkan untuk buffer, ini lebih seperti array c-language yang dapat melakukan operasi pointer. Misalnya, byte pada posisi tertentu dapat secara langsung dimodifikasi dalam metode [indeks].
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Metode Slice tidak mengembalikan buffer baru, tetapi mengembalikan pointer ke lokasi di tengah buffer asli, seperti yang ditunjukkan di bawah ini.
[0x68, 0x65, 0x6c, 0x6c, 0x6f]
^ ^
| |
bin bin.slice (2)
Oleh karena itu, modifikasi buffer yang dikembalikan dengan metode SLICE akan bertindak pada buffer asli, misalnya:
Salinan kode adalah sebagai berikut:
var buffer = buffer baru ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var sub = bin.slice (2);
sub [0] = 0x65;
console.log (buffer); // <buffer 68 65 65 6c 6f>
Jika Anda ingin menyalin buffer, Anda harus terlebih dahulu membuat buffer baru dan menyalin data dalam buffer asli melalui metode .copy.
Ini mirip dengan menerapkan bagian memori baru dan menyalin data dalam memori yang ada. Inilah contohnya.
Salinan kode adalah sebagai berikut:
var buffer = buffer baru ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var dup = buffer baru (bin.length);
buffer.copy (dup);
dup [0] = 0x48;
console.log (buffer); // <buffer 68 65 6c 6c 6f>
console.log (dup); // <buffer 48 65 65 6c 6f>
Singkatnya, Buffer memperluas kemampuan pemrosesan data JS dari string ke data biner sewenang -wenang.
Di atas secara singkat memungkinkan Anda memahami apa itu penyangga. Mari kita bicara tentang cara menggunakannya dan skenario penggunaan spesifik di bawah ini.
Kedua, bicara tentang buffer
JavaScript sangat ramah untuk pemrosesan string, dan apakah itu byte lebar atau string byte tunggal, itu dianggap sebagai string. Node perlu memproses protokol jaringan, basis data operasi, memproses gambar, mengunggah file, dll., Dan juga perlu memproses sejumlah besar data biner. String yang datang bersama mereka jauh dari memenuhi persyaratan ini, sehingga Buffer muncul.
Struktur penyangga
Buffer adalah modul khas yang menggabungkan JavaScript dan C ++. Bagian terkait kinerja diimplementasikan dalam C ++, dan bagian yang tidak berkinerja tidak berkinerja diimplementasikan dalam JavaScript.
Node diinstal ke dalam memori ketika proses dimulai dan memasukkannya ke objek global, jadi tidak perlu memerlukannya.
Objek Buffer: Mirip dengan array, elemen -elemennya adalah dua digit dalam heksadesimal.
Alokasi memori buffer
Alokasi memori objek buffer tidak ada dalam memori heap V8, tetapi mengimplementasikan aplikasi memori pada level node C ++.
Untuk menggunakan aplikasi memori secara efisien, Node menggunakan mekanisme alokasi slab, yang merupakan mekanisme manajemen memori dinamis yang menerapkan berbagai sistem operasi *nix. Ada tiga negara pelat:
(1) Lengkap: keadaan teralokasi sepenuhnya
(2) Parsial: Status Alokasi Parsial
(3) Kosong: Tidak Ditugaskan
Konversi buffer
Objek penyangga dapat dikonversi menjadi string, dan jenis penyandian yang didukung adalah sebagai berikut:
ASCII, UTF-8, UTF-16LE/UCS-2, BASE64, BINARY, HEX
String ke buffer
Buffer baru (str, [encoding]), Default UTF-8
buf.write (string, [offset], [length], [encoding])
Buffer ke string
buf.tostring ([encoding], [start], [end])
Jenis pengkodean yang tidak didukung oleh buffer
Tentukan apakah itu mendukungnya dengan buffer.isencoding (encoding)
ICONV-Lite: Implementasi JavaScript murni, lebih ringan, kinerja yang lebih baik tanpa konversi C ++ ke JavaScript
ICONV: Memanggil perpustakaan libiconv di C ++ selesai
Penyambungan penyangga
Catatan "res.on ('data', function (chunk) {})", di mana chunk parameter adalah objek buffer. Langsung menggunakan + jahitan akan secara otomatis dikonversi menjadi string. Untuk karakter byte yang luas, kode kacau dapat terjadi.
Larutan:
(1) Melalui metode setencoding () dalam aliran yang dapat dibaca, metode ini memungkinkan acara data untuk melewati objek buffer, tetapi string yang dikodekan, dan modul StringEncoder digunakan secara internal.
(2) Menyimpan objek buffer ke dalam array, dan akhirnya merakitnya menjadi buffer besar dan kemudian menyandikannya menjadi output string.
Buffer banyak digunakan dalam file I/O dan jaringan I/O, dan kinerjanya sangat penting dan jauh lebih tinggi daripada string biasa.
Selain hilangnya kinerja konversi string, saat menggunakan buffer, pengaturan HighWatermark sangat penting untuk dampak kinerja saat membaca file.
A. Pengaturan Highwatermark berdampak pada alokasi dan penggunaan memori buffer.
B. Pengaturan Highwatermark terlalu kecil, yang dapat menyebabkan terlalu banyak panggilan sistem.
Kapan saya harus menggunakan buffer, kapan saya tidak harus menggunakannya ------- JavaScript murni mendukung kode unicode tetapi tidak mendukung biner. Saat memecahkan aliran TCP atau aliran file, perlu untuk memproses aliran. Ketika kita menyimpan string non-UTF-8, format biner dan lainnya, kita harus menggunakan "buffer".
3. Perkenalkan contoh
Salinan kode adalah sebagai berikut:
var buf = buffer baru ("Ini adalah Tes CONDAT TEXT!"), str = "Ini adalah Tes Concat Teks!" ;
Console.Time ("Tes Buffer Concat!");
var list = [];
var len = 100000 * buf.length;
untuk (var i = 0; i <100000; i ++) {
list.push (buf);
len += buf.length;
}
var s1 = buffer.concat (daftar, len) .toString ();
Console.Timeend ("Tes Buffer Concat!");
Console.Time ("Tes String Concat!");
var list = [];
untuk (var i = 100000; i> = 0; i--) {
list.push (str);
}
var s2 = list.join ("");
Console.TimeEnd ("String Concat Test!");
Berikut ini adalah hasil berjalan:
Kecepatan membaca jelas lebih cepat, dan buffer juga membutuhkan pengoperasian tostring (). Jadi ketika kita menyimpan string, kita masih perlu menggunakan string. Bahkan jika kita menyambungkan string dalam string besar, kecepatan string tidak akan lebih lambat dari buffer.
Jadi kapan kita perlu menggunakan buffer lagi? Ketika tidak ada cara, ketika kita menyimpan string non-UTF-8, format biner dan lainnya, kita harus menggunakannya.
Empat, mari kita ringkas
(1) JavaScript cocok untuk memproses data yang dikodekan unicode, tetapi tidak ramah untuk pemrosesan data biner.
(2), jadi saat memproses aliran TCP atau sistem file, perlu untuk memproses aliran oktet.
(3), Node memiliki beberapa metode untuk memproses, membuat dan mengonsumsi aliran oktet.
(4) Data mentah disimpan dalam contoh buffer. Buffer mirip dengan array integer, tetapi ingatannya dialokasikan di luar tumpukan V8. Ukuran buffer tidak dapat diubah.
(5), jenis pengkodean yang diproses adalah: ASCII, UTF8, UTF16LE, UCS2 (Alias untuk UTF16LE), Base64, Biner, Hex.
(6) Buffer adalah elemen global, dan instance buffer diperoleh dengan buffer baru secara langsung ().