Bagaimana saya bisa mengubah buffer biner NodeJS menjadi JavaScript ArrayBuffer?
javascript
node.js
binary
buffer
arraybuffer
Drake Amara
sumber
sumber
Array
. Jadi untuk menyimpan banyak pelampung yang Anda butuhkan diFloat32Array
mana dibutuhkan 4 byte. Dan jika Anda ingin serialisasi cepat dari float ke file yang Anda butuhkanBuffer
, karena serialisasi ke JSON membutuhkan waktu lama.Jawaban:
Instance
Buffer
juga instanceUint8Array
dalam node.js 4.x dan lebih tinggi. Dengan demikian, solusi paling efisien adalah mengaksesbuf.buffer
properti secara langsung, seperti https://stackoverflow.com/a/31394257/1375574 . Konstruktor Buffer juga mengambil argumen ArrayBufferView jika Anda perlu pergi ke arah lain.Perhatikan bahwa ini tidak akan membuat salinan, yang berarti bahwa menulis ke ArrayBufferView apa pun akan menulis hingga contoh Buffer asli.
Dalam versi yang lebih lama, node.js memiliki kedua ArrayBuffer sebagai bagian dari v8, tetapi kelas Buffer menyediakan API yang lebih fleksibel. Untuk membaca atau menulis ke ArrayBuffer, Anda hanya perlu membuat tampilan dan menyalinnya.
Dari Buffer ke ArrayBuffer:
Dari ArrayBuffer ke Buffer:
sumber
size&0xfffffffe
, salin integer 32-bit, lalu, jika ada 1 byte tersisa, salin integer 8-bit, jika 2 byte, salin integer 16-bit, dan jika 3 byte, salin integer 16-bit dan 8-bit.ab
dikembalikan? Tidak ada yang dilakukanab
? Saya selalu mendapatkan{}
hasilnya.slice()
Metode mengembalikan yang baruArrayBuffer
yang isinya salinanArrayBuffer
byte ini dari awal, inklusif, hingga akhir, eksklusif.' - MDNArrayBuffer.prototype.slice()
Tidak ada dependensi, tercepat, Node.js 4.x dan yang lebih baru
Buffer
s adalahUint8Array
s, jadi Anda hanya perlu mengiris (menyalin) wilayah dukungannyaArrayBuffer
.The
slice
hal-hal dan offset diperlukan karena kecilBuffer
s (kurang dari 4 kB secara default, setengah ukuran kolam ) dapat dilihat pada bersamaArrayBuffer
. Tanpa mengiris, Anda bisa berakhir denganArrayBuffer
berisi data dari yang lainBuffer
. Lihat penjelasan dalam dokumen .Jika pada akhirnya Anda membutuhkan
TypedArray
, Anda dapat membuatnya tanpa menyalin data:Tidak ada dependensi, kecepatan sedang, versi Node.js apa pun
Gunakan jawaban Martin Thomson , yang berjalan dalam O (n) waktu. (Lihat juga balasan saya untuk komentar pada jawabannya tentang non-optimisasi. Menggunakan DataView lambat. Bahkan jika Anda perlu membalik byte, ada cara yang lebih cepat untuk melakukannya.)
Ketergantungan, cepat, Node.js ≤ 0,12 atau iojs 3.x
Anda dapat menggunakan https://www.npmjs.com/package/memcpy untuk menuju salah satu arah (Buffer ke ArrayBuffer dan kembali). Ini lebih cepat daripada jawaban lain yang diposting di sini dan merupakan perpustakaan yang ditulis dengan baik. Simpul 0,12 hingga iojs 3.x memerlukan garpu ngossen (lihat ini ).
sumber
.byteLength
dan.byteOffset
didokumentasikan?var ab = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
menyelamatkan hari saya"Dari ArrayBuffer ke Buffer" dapat dilakukan dengan cara ini:
sumber
Cara yang lebih cepat untuk menulisnya
Namun, ini tampaknya berjalan kira-kira 4 kali lebih lambat daripada fungsi toArrayBuffer yang disarankan pada buffer dengan 1024 elemen.
sumber
Buffer
juga instanceUint8Array
dalam Node.js 4.x dan lebih tinggi. Untuk versi Node.js yang lebih rendah Anda harus mengimplementasikan suatutoArrayBuffer
fungsi.1. A
Buffer
hanyalah tampilan untuk melihat ke dalamArrayBuffer
.A
📜 Node.js 9.4.0Buffer
, pada kenyataannya, adalah aFastBuffer
, yangextends
(mewarisi dari)Uint8Array
, yang merupakan tampilan satuan oktet ("pengakses parsial") dari memori aktual, anArrayBuffer
./lib/buffer.js#L65-L73
2. Ukuran
ArrayBuffer
dan ukuran tampilan dapat bervariasi.Alasan # 1:
Buffer.from(arrayBuffer[, byteOffset[, length]])
.Dengan
Buffer.from(arrayBuffer[, byteOffset[, length]])
, Anda dapat membuatBuffer
dengan menentukan dasarnyaArrayBuffer
dan posisi serta ukuran tampilan.Alasan # 2:
FastBuffer
alokasi memori.Ini mengalokasikan memori dalam dua cara berbeda tergantung pada ukurannya.
ArrayBuffer
yang persis sesuai dengan memori yang diperlukan./lib/buffer.js#L306-L320
📜 Node.js 9.4.0/lib/buffer.js#L98-L100
Apa yang Anda maksud dengan " kumpulan memori ?"
Kumpulan memori adalah blok memori pra-alokasi ukuran tetap untuk menjaga potongan memori berukuran kecil untuk
Buffer
s. Menggunakannya membuat potongan memori ukuran kecil tetap rapat, sehingga mencegah fragmentasi yang disebabkan oleh manajemen yang terpisah (alokasi dan deallokasi) dari potongan memori ukuran kecil.Dalam kasus ini, kumpulan memori adalah
ArrayBuffer
s yang ukurannya 8 KiB secara default, yang ditentukan dalamBuffer.poolSize
. Ketika akan menyediakan potongan memori ukuran kecil untuk aBuffer
, itu memeriksa apakah kumpulan memori terakhir memiliki cukup memori yang tersedia untuk menangani ini; jika demikian, itu menciptakanBuffer
yang “dilihat” potongan parsial diberikan dari kolam memori, jika tidak, itu menciptakan kolam memori baru dan sebagainya.Anda dapat mengakses dasar
ArrayBuffer
dari aBuffer
. TheBuffer
'sbuffer
properti (yaitu, diwarisi dariUint8Array
) memegang itu. Sebuah “kecil”Buffer
'sbuffer
properti merupakanArrayBuffer
yang mewakili seluruh kolam memori. Jadi dalam hal ini,ArrayBuffer
danBuffer
ukurannya bervariasi.3. Jadi kita perlu mengekstrak memori itu " dilihat ."
Sebuah
ArrayBuffer
adalah tetap dalam ukuran, sehingga kita perlu untuk mengambil keluar dengan membuat salinan bagian. Untuk melakukan hal ini, kita menggunakanBuffer
'sbyteOffset
properti danlength
properti , yang diwarisi dariUint8Array
, dan yangArrayBuffer.prototype.slice
metode , yang membuat salinan bagian dariArrayBuffer
. Theslice()
Metode -ing disini terinspirasi oleh @ZachB .4. Peningkatan kinerja
Jika Anda menggunakan hasil sebagai hanya-baca, atau apa-apa untuk mengubah masukan
Buffer
s'isi , Anda dapat menghindari yang tidak perlu menyalin memori.sumber
obtain_arraybuffer
:buf.buffer.subarray
sepertinya tidak ada. Apakah maksud Anda dibuf.buffer.slice
sini?ArrayBuffer.prototype.slice
dan kemudian memodifikasinyaUint8Array.prototype.subarray
. Oh, dan aku salah melakukannya. Mungkin agak bingung saat itu. Semua baik-baik saja sekarang, terima kasih.Menggunakan paket NPM sangat baik sebagai berikut:
to-arraybuffer
.Atau, Anda bisa menerapkannya sendiri. Jika buffer Anda dipanggil
buf
, lakukan ini:sumber
Anda dapat menganggap
ArrayBuffer
sebagai diketikBuffer
.Sebuah
ArrayBuffer
karena itu selalu membutuhkan jenis (yang disebut "Array Buffer View"). Biasanya, Array Buffer View memiliki tipeUint8Array
atauUint16Array
.Ada artikel bagus dari Renato Mangini tentang konversi antara ArrayBuffer dan String .
Saya telah merangkum bagian-bagian penting dalam contoh kode (untuk Node.js). Ini juga menunjukkan bagaimana mengkonversi antara yang diketik
ArrayBuffer
dan yang tidak diketikBuffer
.sumber
Saya mencoba di atas untuk Float64Array dan itu tidak berhasil.
Saya akhirnya menyadari bahwa benar-benar data yang perlu dibaca 'KEPADA' tampilan dalam potongan yang benar. Ini berarti membaca 8 byte sekaligus dari Buffer sumber.
Pokoknya inilah yang akhirnya saya dapatkan dengan ...
sumber
Buffer.read*
metode semua lambat, juga.Proxy ini akan mengekspos buffer sebagai salah satu dari TypedArrays, tanpa salinan apa pun. :
https://www.npmjs.com/package/node-buffer-as-typedarray
Ini hanya bekerja pada LE, tetapi dapat dengan mudah dipindahkan ke BE. Juga, tidak pernah benar-benar menguji seberapa efisien ini.
sumber
Sekarang ada paket npm yang sangat berguna untuk ini:
buffer
https://github.com/feross/bufferIa mencoba menyediakan API yang 100% identik dengan API Penyangga simpul dan memungkinkan:
dan beberapa lagi.
sumber
NodeJS, pada satu titik (saya pikir itu v0.6.x) mendapat dukungan ArrayBuffer. Saya membuat perpustakaan kecil untuk encoding dan decoding base64 di sini , tetapi sejak memperbarui ke v0.7, tes (pada NodeJS) gagal. Saya sedang berpikir untuk menciptakan sesuatu yang menormalkan ini, tetapi sampai saat itu, saya kira asli Node
Buffer
harus digunakan.sumber
Saya sudah memperbarui simpul saya ke Versi 5.0.0 Dan saya bekerja dengan ini:
Saya menggunakannya untuk memeriksa image disk VHD saya.
sumber
toArrayBuffer(new Buffer([1,2,3]))
->['01', '02', '03']
- ini mengembalikan array string, bukan bilangan bulat / byte.