Converting between strings and ArrayBuffers

后端 未结 24 883
慢半拍i
慢半拍i 2020-11-22 04:50

Is there a commonly accepted technique for efficiently converting JavaScript strings to ArrayBuffers and vice-versa? Specifically, I\'d like to be able to write the contents

24条回答
  •  礼貌的吻别
    2020-11-22 05:25

    (Update Please see the 2nd half of this answer, where I have (hopefully) provided a more complete solution.)

    I also ran into this issue, the following works for me in FF 6 (for one direction):

    var buf = new ArrayBuffer( 10 );
    var view = new Uint8Array( buf );
    view[ 3 ] = 4;
    alert(Array.prototype.slice.call(view).join(""));
    

    Unfortunately, of course, you end up with ASCII text representations of the values in the array, rather than characters. It still (should be) much more efficient than a loop, though. eg. For the example above, the result is 0004000000, rather than several null chars & a chr(4).

    Edit:

    After looking on MDC here, you may create an ArrayBuffer from an Array as follows:

    var arr = new Array(23);
    // New Uint8Array() converts the Array elements
    //  to Uint8s & creates a new ArrayBuffer
    //  to store them in & a corresponding view.
    //  To get at the generated ArrayBuffer,
    //  you can then access it as below, with the .buffer property
    var buf = new Uint8Array( arr ).buffer;
    

    To answer your original question, this allows you to convert ArrayBuffer <-> String as follows:

    var buf, view, str;
    buf = new ArrayBuffer( 256 );
    view = new Uint8Array( buf );
    
    view[ 0 ] = 7; // Some dummy values
    view[ 2 ] = 4;
    
    // ...
    
    // 1. Buffer -> String (as byte array "list")
    str = bufferToString(buf);
    alert(str); // Alerts "7,0,4,..."
    
    // 1. String (as byte array) -> Buffer    
    buf = stringToBuffer(str);
    alert(new Uint8Array( buf )[ 2 ]); // Alerts "4"
    
    // Converts any ArrayBuffer to a string
    //  (a comma-separated list of ASCII ordinals,
    //  NOT a string of characters from the ordinals
    //  in the buffer elements)
    function bufferToString( buf ) {
        var view = new Uint8Array( buf );
        return Array.prototype.join.call(view, ",");
    }
    // Converts a comma-separated ASCII ordinal string list
    //  back to an ArrayBuffer (see note for bufferToString())
    function stringToBuffer( str ) {
        var arr = str.split(",")
          , view = new Uint8Array( arr );
        return view.buffer;
    }
    

    For convenience, here is a function for converting a raw Unicode String to an ArrayBuffer (will only work with ASCII/one-byte characters)

    function rawStringToBuffer( str ) {
        var idx, len = str.length, arr = new Array( len );
        for ( idx = 0 ; idx < len ; ++idx ) {
            arr[ idx ] = str.charCodeAt(idx) & 0xFF;
        }
        // You may create an ArrayBuffer from a standard array (of values) as follows:
        return new Uint8Array( arr ).buffer;
    }
    
    // Alerts "97"
    alert(new Uint8Array( rawStringToBuffer("abc") )[ 0 ]);
    

    The above allow you to go from ArrayBuffer -> String & back to ArrayBuffer again, where the string may be stored in eg. .localStorage :)

    Hope this helps,

    Dan

提交回复
热议问题