2013-09-03 56 views
5

Nếu tôi muốn tạo bộ tạo mảng, tôi viết: var buff = new ArrayBuffer(size)Thay đổi kích thước ArrayBuffer

Nhưng làm cách nào để thay đổi kích thước bộ đệm hiện có? Ý tôi là, thêm một số byte vào cuối bộ đệm.

Trả lời

4
var buf = new ArrayBuffer(32); 
buf[31] = 43; 
var buff = new ArrayBuffer(buf.byteLength*2); 

for (var i=0;i<buf.byteLength;i++){ 
    buff[i] = buf[i]; 
} 

buf = buff; 

Tôi đã thực hiện nó trong C++ như thế này. Chỉ cần thực hiện một mảng lớn hơn và sao chép các nội dung trên và sau đó trả về mảng lớn hơn và đặt nó như là bản gốc.

+5

Trong JS, ta nên sử dụng TypedArray.prototype.set() để sao chép giữa các mảng, như Jon Lennart Aasenden đã đề xuất. – artem

+0

Tôi rất lúng túng vì lý do tại sao điều này được chấp nhận. ** Nội dung của một 'ArrayBuffer' không thể được truy cập _directly_ với' [] ', nhưng chỉ thông qua _Views_ như _Typed arrays_ và' DataView '. ** Điều gì của mã là PROPERTIES, không phải CONTENT của chúng. Bạn thấy nội dung: 'console.log (new Uint8Array (buf));'. –

6

Bạn không thể.

From the MDN:

Các ArrayBuffer là một kiểu dữ liệu được sử dụng để đại diện cho một generic, cố định chiều dài nhị phân đệm dữ liệu.

Tôi không biết những gì bạn cố gắng làm nhưng rõ ràng là bạn không sử dụng chúng như thế nào chúng có nghĩa là để được sử dụng.

This page là điểm khởi đầu tốt để tìm hiểu cách sử dụng các mảng đã nhập trong JavaScript.

+0

thì làm sao là nó có thể tạo một hình mới, bắt đầu với các yếu tố cũ không? –

+0

Bạn đang tìm kiếm quan điểm? Xem https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/ArrayBufferView Nếu không có một số ví dụ trong trang tôi liên kết đến trong câu trả lời của tôi. –

4

Điều bạn đang tìm kiếm là phương pháp "được đặt". Sau khi tạo một mảng mới, lớn hơn, chỉ cần gọi hàm set và sao chép nội dung cũ hơn.

+1

Không có phương thức '.set()' trên 'ArrayBuffer'. –

+0

Bạn phải tạo một mảng kiểu chữ (xem) trên 'ArrayBuffer', sau đó gọi' set' trên đó. –

6

Không được đặt trên chính ArrayBuffer. Tuy nhiên, có set trên TypedArray. Sử dụng như thế này:

var oldBuffer = new ArrayBuffer(20); 

var newBuffer = new ArrayBuffer(40); 
new Uint8Array(newBuffer).set(oldBuffer); 
+0

set() hoạt động nhưng không sử dụng như vậy bởi vì tập không trả về một giá trị mà bạn sẽ không có con trỏ tới mảng mới – Curtis

+0

ví dụ được đưa ra chỉ hoạt động tốt. mã không cần poiinter tới 'Uint8Array' vì nó chỉ sử dụng nó để truy cập hàm' set' – gman

1

Cách làm đó sẽ là ArrayBuffer.transfer(oldBuffer, newByteLength), như vậy:

var buffA = new ArrayBuffer(30); 
var buffB = ArrayBuffer.transfer(buffA, 40); 

// buffA is now an empty array buffer (`buffA.byteLength === 0`) 
// whereas buffB is a new buffer that starts with a's contents 
// and ends with 10 bytes that are 0s. 

// Much faster than manually copying. You could even just do: 

var buffA = new ArrayBuffer(30); 
buffA = ArrayBuffer.transfer(buffA, 40); 

// Or as a prototype method 

ArrayBuffer.prototype.resize = function(newByteLength) { 
    return ArrayBuffer.transfer(this, newByteLength); 
} 

var buffA = new ArrayBuffer(30); 
buffA = buffA.resize(40); 

Tuy nhiên (tính đến tháng 10 năm 2017) có là 0% hỗ trợ trình duyệt (thậm chí không hỗ trợ Node.js) và thậm chí chưa được soạn thảo.


Cho đến đây là có sẵn, bạn có thể sử dụng polyfill đưa ra trên trang web, mà các bản sao 8 byte tại một thời điểm, như vậy là tương đối nhanh chóng cho mảng lớn (Mặc dù nó không trống mảng nhất định, đó là không thể làm).

Dưới đây là một phiên bản sửa đổi sử dụng TypeArray.prototype.set thay vì cho vòng:

if (!ArrayBuffer.transfer) { 
    ArrayBuffer.transfer = function(oldBuffer, newByteLength) { 
    var srcBuffer = Object(oldBuffer); 
    var destBuffer = new ArrayBuffer(newByteLength); 
    if (!(srcBuffer instanceof ArrayBuffer) || !(destBuffer instanceof ArrayBuffer)) { 
     throw new TypeError('Source and destination must be ArrayBuffer instances'); 
    } 
    var copylen = Math.min(srcBuffer.byteLength, destBuffer.byteLength); 

    /* Copy 64 bits at a time */ 
    var length = Math.trunc(copylen/64); 
    (new Float64Array(destBuffer, 0, length)) 
     .set(new Float64Array(srcBuffer, 0, length)); 

    /* Copy the remaining 0 to 63 bits, 1 byte at a time */ 
    var offset = length * 64; 
    length = copylen - offset; 
    (new Uint8Array(srcBuffer, offset, length)) 
     .set(new Uint8Array(destBuffer, offset, length)); 

    return destBuffer; 
    }; 
} 
Các vấn đề liên quan