是否有一种普遍接受的技术可以有效地将JavaScript字符串转换为arraybuffer,反之亦然?具体来说,我希望能够将ArrayBuffer的内容写入localStorage,然后再将其读回来。
当前回答
下面是一个Typescript的工作实现:
bufferToString(buffer: ArrayBuffer): string {
return String.fromCharCode.apply(null, Array.from(new Uint16Array(buffer)));
}
stringToBuffer(value: string): ArrayBuffer {
let buffer = new ArrayBuffer(value.length * 2); // 2 bytes per char
let view = new Uint16Array(buffer);
for (let i = 0, length = value.length; i < length; i++) {
view[i] = value.charCodeAt(i);
}
return buffer;
}
在使用crypt .subtle时,我已经使用它进行了许多操作。
其他回答
(更新请参阅这个答案的后半部分,我(希望)提供了一个更完整的解决方案。)
我也遇到了这个问题,以下是我在FF 6中的工作(一个方向):
var buf = new ArrayBuffer( 10 );
var view = new Uint8Array( buf );
view[ 3 ] = 4;
alert(Array.prototype.slice.call(view).join(""));
当然,不幸的是,您最终得到的是数组中值的ASCII文本表示,而不是字符。尽管如此,它仍然(应该)比循环更有效。 如。对于上面的例子,结果是0004000000,而不是几个空字符&一个chr(4)。
编辑:
看完这里的MDC,你可以从一个数组创建一个ArrayBuffer,如下所示:
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;
为了回答你最初的问题,这允许你像下面这样转换ArrayBuffer <-> String:
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;
}
为了方便起见,这里有一个将原始Unicode字符串转换为ArrayBuffer的函数(只适用于ASCII/单字节字符)
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 ]);
上面允许你从ArrayBuffer -> String返回到ArrayBuffer,在那里字符串可能存储在eg. . localstorage:)
希望这能有所帮助,
Dan
我不建议使用已弃用的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);
}
请注意,与已弃用的方法相比,这是多么干净和不那么臃肿……是的,这绝对是需要考虑的。
Blob比String.fromCharCode(null,array)慢得多;
但如果数组缓冲区太大,就会失败。我发现的最佳解决方案是使用String.fromCharCode(null,数组);并将其拆分为不会破坏堆栈的操作,但每次比单个char更快。
大数组缓冲区的最佳解决方案是:
function arrayBufferToString(buffer){
var bufView = new Uint16Array(buffer);
var length = bufView.length;
var result = '';
var addition = Math.pow(2,16)-1;
for(var i = 0;i<length;i+=addition){
if(i + addition > length){
addition = length - i;
}
result += String.fromCharCode.apply(null, bufView.subarray(i,i+addition));
}
return result;
}
我发现这比使用blob快20倍。它也适用于超过100mb的大字符串。
最近,我还需要为我的一个项目做这件事,所以做了一个很好的研究,并从谷歌的开发者社区得到了一个结果,它以简单的方式陈述了这一点:
用于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.
欲了解更多详细信息,请参考谷歌的博客。
下面是一个Typescript的工作实现:
bufferToString(buffer: ArrayBuffer): string {
return String.fromCharCode.apply(null, Array.from(new Uint16Array(buffer)));
}
stringToBuffer(value: string): ArrayBuffer {
let buffer = new ArrayBuffer(value.length * 2); // 2 bytes per char
let view = new Uint16Array(buffer);
for (let i = 0, length = value.length; i < length; i++) {
view[i] = value.charCodeAt(i);
}
return buffer;
}
在使用crypt .subtle时,我已经使用它进行了许多操作。
推荐文章
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 未捕获的SyntaxError:
- [].slice的解释。调用javascript?
- jQuery日期/时间选择器
- 我如何预填充一个jQuery Datepicker文本框与今天的日期?
- 数组的indexOf函数和findIndex函数的区别
- jQuery添加必要的输入字段
- Access-Control-Allow-Origin不允许Origin < Origin >