是否有一种普遍接受的技术可以有效地将JavaScript字符串转换为arraybuffer,反之亦然?具体来说,我希望能够将ArrayBuffer的内容写入localStorage,然后再将其读回来。


当前回答

最近,我还需要为我的一个项目做这件事,所以做了一个很好的研究,并从谷歌的开发者社区得到了一个结果,它以简单的方式陈述了这一点:

用于ArrayBuffer to String

function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint16Array(buf));
}
// Here Uint16 can be different like Uinit8/Uint32 depending upon your buffer value type.

用于字符串到ArrayBuffer

function str2ab(str) {
  var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
  var bufView = new Uint16Array(buf);
  for (var i=0, strLen=str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}
//Same here also for the Uint16Array.

欲了解更多详细信息,请参考谷歌的博客。

其他回答

我用了这个,对我很有用。

function arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}



function base64ToArrayBuffer(base64) {
    var binary_string =  window.atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++)        {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes.buffer;
}

你可以使用Encoding标准中的TextEncoder和TextDecoder,该标准由stringencoding库填充,用于将字符串转换为ArrayBuffers:

var uint8array = new TextEncoder().encode(string);
var string = new TextDecoder(encoding).decode(uint8array);

我不建议使用已弃用的api,如BlobBuilder

Blob对象早已弃用了BlobBuilder。将Dennis回答中的代码(其中使用了BlobBuilder)与下面的代码进行比较:

function arrayBufferGen(str, cb) {

  var b = new Blob([str]);
  var f = new FileReader();

  f.onload = function(e) {
    cb(e.target.result);
  }

  f.readAsArrayBuffer(b);

}

请注意,与已弃用的方法相比,这是多么干净和不那么臃肿……是的,这绝对是需要考虑的。

请看这里:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/StringView (基于JavaScript ArrayBuffer接口的类似c语言的字符串接口)

在使用了mangini的从ArrayBuffer转换到String的解决方案- ab2str(这是我发现的最优雅和有用的一个-谢谢!)之后,我在处理大型数组时遇到了一些问题。更具体地说,调用String.fromCharCode.apply(null, new Uint16Array(buf));抛出错误:

传递给Function.prototype.apply的参数数组太大。

为了解决它(绕过),我决定处理输入ArrayBuffer块。所以修改后的解是:

function ab2str(buf) {
   var str = "";
   var ab = new Uint16Array(buf);
   var abLen = ab.length;
   var CHUNK_SIZE = Math.pow(2, 16);
   var offset, len, subab;
   for (offset = 0; offset < abLen; offset += CHUNK_SIZE) {
      len = Math.min(CHUNK_SIZE, abLen-offset);
      subab = ab.subarray(offset, offset+len);
      str += String.fromCharCode.apply(null, subab);
   }
   return str;
}

块大小设置为2^16,因为这是我发现在我的开发环境中工作的大小。设置一个更高的值会导致同样的错误再次发生。可以通过将CHUNK_SIZE变量设置为不同的值来更改它。偶数是很重要的。

性能注意事项—我没有对此解决方案进行任何性能测试。但是,由于它基于前面的解决方案,并且可以处理大型数组,所以我认为没有理由不使用它。