(Mise à jour , Veuillez voir la 2e moitié de cette réponse, où j'ai (je l'espère) ont fourni une solution plus complète.)
J'ai aussi rencontré ce problème, les travaux suivants, pour moi, en FF 6 (dans un sens):
var buf = new ArrayBuffer( 10 );
var view = new Uint8Array( buf );
view[ 3 ] = 4;
alert(Array.prototype.slice.call(view).join(""));
Malheureusement, bien sûr, vous vous retrouvez avec du texte ASCII représentations de les valeurs dans le tableau, plutôt que des caractères. - Il encore (devrait être) beaucoup plus efficace qu'une boucle.
par exemple. Pour l'exemple ci-dessus, le résultat est 0004000000
, au lieu de plusieurs caractères null & chr(4).
Edit:
Après recherche sur MDC ici, vous pouvez créer un ArrayBuffer
d'un Array
comme suit:
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;
Pour répondre à votre question de départ, ce qui vous permet de convertir ArrayBuffer
<-> String
comme suit:
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;
}
Pour plus de commodité, voici un function
pour la conversion d'un raw Unicode String
d'un ArrayBuffer
(ne fonctionne qu'avec ASCII/caractères d'un octet)
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 ]);
Le ci-dessus vous permettent d'aller d' ArrayBuffer
-> String
& retour à ArrayBuffer
, là où la chaîne peut être stockée dans eg. .localStorage
:)
Espérons que cela aide,
Dan
1 votes
Je n'ai pas d'expérience dans ce domaine, mais à en juger par la documentation de l'API ( khronos.org/registry/typedarray/specs/latest ) si vous construisez un
Int8Array
ArrayBufferView
il pourrait être possible d'utiliser simplement la notation entre crochets pour copier les caractèresstring[i] = buffer[i]
et vice versa.2 votes
@FK82, cela semble être une approche raisonnable (utilisation de
Uint16Array
s pour les caractères 16 bits de JS), mais les chaînes JavaScript sont immuables et vous ne pouvez pas assigner directement une position de caractère. Je devrais toujours copierString.fromCharCode(x)
de chaque valeur dans leUint16Array
à une normaleArray
et ensuite appeler.join()
sur leArray
.0 votes
@kpozin : Vrai, je n'ai pas vraiment pensé à ça.
7 votes
@kpozin Il s'avère que la plupart des moteurs JS modernes ont optimisé la concaténation des chaînes de caractères à un point tel qu'il est moins coûteux d'utiliser tout simplement
string += String.fromCharCode(buffer[i]);
. Il semble étrange qu'il n'y ait pas de méthodes intégrées pour convertir les chaînes de caractères en tableaux typés. Ils devaient savoir que quelque chose comme ça arriverait.1 votes
ArrayBuffer.toString() fonctionne bien pour moi.
1 votes
@citizen conn - Je ne sais pas quel navigateur vous utilisez, mais sur Chrome arrayBuffer.toString() donne juste "[objet ArrayBuffer]". Ce n'est pas très utile.
0 votes
@download, Citation nécessaire . En effet, ce n'est pas tout à fait logiquement possible puisque la concaténation est faite dynamiquement (par opposition à une précompilation). Exécution de
+=
dans une boucle vous donneraj de sérieux goulots d'étranglement.0 votes
Version asynchrone :
str = await new Response(str).arrayBuffer()
0 votes
@mrec Convertissez d'abord le ArrayBuffer en un TypedArray.