Gibt es eine allgemein akzeptierte Technik, um JavaScript-Strings effizient in ArrayBuffers und umgekehrt zu konvertieren? Insbesondere möchte ich in der Lage sein, den Inhalt eines ArrayBuffers in localStorage
zu schreiben und ihn zurückzulesen.
Update 2016 - fünf Jahre später gibt es nun neue Methoden in den Spezifikationen (siehe Unterstützung unten), um zwischen Strings und typisierten Arrays mit der richtigen Kodierung zu konvertieren.
Die TextEncoder
steht für :
Die
TextEncoder
-Schnittstelle stellt einen Encoder für eine bestimmte Methode dar das ist eine bestimmte Zeichencodierung, wieutf-8
,Ein Encoder nimmt einen Strom von Codepunkten als Eingabe und gibt einen Bytestrom aus.iso-8859-2
,koi8
,cp1261
,gbk
, ...
Notiz ändern, da das Obige geschrieben wurde: (ibid.)
Hinweis: Firefox, Chrome und Opera haben früher die Kodierung unterstützt andere Typen als utf-8 (wie utf-16, iso-8859-2, koi8, cp1261 und gbk). Ab Firefox 48 [...], Chrome 54 [...] und Opera 41, Nr Andere Codierungstypen als utf-8 sind verfügbar, um mit .__ übereinzustimmen. die spez. *
*) Aktualisierte Spezifikationen (W3) und hier (whatwg).
Nachdem Sie eine Instanz von TextEncoder
erstellt haben, wird eine Zeichenfolge verwendet und mit einem bestimmten Codierungsparameter codiert:
if (!("TextEncoder" in window))
alert("Sorry, this browser does not support TextEncoder...");
var enc = new TextEncoder(); // always utf-8
console.log(enc.encode("This is a string converted to a Uint8Array"));
Sie verwenden dann natürlich den .buffer
-Parameter für den resultierenden Uint8Array
, um die darunterliegende ArrayBuffer
bei Bedarf in eine andere Ansicht zu konvertieren.
Stellen Sie nur sicher, dass die Zeichen in der Zeichenfolge dem Kodierungsschema entsprechen. Wenn Sie beispielsweise Zeichen außerhalb des UTF-8-Bereichs verwenden, werden diese in zwei Byte statt einem Byte kodiert.
Zur allgemeinen Verwendung würden Sie die UTF-16-Codierung für Dinge wie localStorage
verwenden.
Der umgekehrte Prozess verwendet ebenfalls die TextDecoder
:
Die
TextDecoder
-Schnittstelle repräsentiert einen Decoder für eine bestimmte Methode das ist eine bestimmte Zeichencodierung, wieutf-8
,iso-8859-2
,koi8
,cp1261
,gbk
, ... Ein Decoder nimmt einen Stream von Bytes als Eingabe auf und gibt .__ aus. ein Strom von Codepunkten.
Alle verfügbaren Dekodierungsarten finden Sie hier .
if (!("TextDecoder" in window))
alert("Sorry, this browser does not support TextDecoder...");
var enc = new TextDecoder("utf-8");
var arr = new Uint8Array([84,104,105,115,32,105,115,32,97,32,85,105,110,116,
56,65,114,114,97,121,32,99,111,110,118,101,114,116,
101,100,32,116,111,32,97,32,115,116,114,105,110,103]);
console.log(enc.decode(arr));
Eine Alternative dazu ist die Verwendung der StringView
-Bibliothek (lizenziert als lgpl-3.0), deren Ziel:
- erstellen einer C-ähnlichen Schnittstelle für Zeichenfolgen (d. h. ein Array von Zeichencodes - ein ArrayBufferView in JavaScript) basierend auf der JavaScript ArrayBuffer-Schnittstelle
- eine stark erweiterbare Bibliothek erstellen, die jeder durch das Hinzufügen von Methoden zum Objekt StringView.prototype erweitern kann
- erstellen einer Sammlung von Methoden für solche stringähnlichen Objekte (seit jetzt: stringViews), die strikt auf Zahlenarrays angewendet werden anstatt neue unveränderliche JavaScript-Zeichenfolgen zu erstellen
- zur Verwendung mit anderen Unicode-Kodierungen als den Standard-UTF-16-DOMStrings von JavaScript
gibt viel mehr Flexibilität. Es ist jedoch erforderlich, dass wir diese Bibliothek verlinken oder einbetten, während TextEncoder
/TextDecoder
in moderne Browser integriert ist.
Stand Juli/2018:
TextEncoder
(experimentell, auf Standardspur)
Chrome | Edge | Firefox | IE | Opera | Safari
----------|-----------|-----------|-----------|-----------|-----------
38 | ? | 19° | - | 25 | -
Chrome/A | Edge/mob | Firefox/A | Opera/A |Safari/iOS | Webview/A
----------|-----------|-----------|-----------|-----------|-----------
38 | ? | 19° | ? | - | 38
°) 18: Firefox 18 implemented an earlier and slightly different version
of the specification.
WEB WORKER SUPPORT:
Experimental, On Standard Track
Chrome | Edge | Firefox | IE | Opera | Safari
----------|-----------|-----------|-----------|-----------|-----------
38 | ? | 20 | - | 25 | -
Chrome/A | Edge/mob | Firefox/A | Opera/A |Safari/iOS | Webview/A
----------|-----------|-----------|-----------|-----------|-----------
38 | ? | 20 | ? | - | 38
Data from MDN - `npm i -g mdncomp` by epistemex
Obwohl Dennis und gengkev Lösungen zur Verwendung von Blob/FileReader funktionieren, würde ich diesen Ansatz nicht empfehlen. Es ist eine asynchrone Herangehensweise an ein einfaches Problem und viel langsamer als eine direkte Lösung. Ich habe einen Post in html5rocks mit einer einfacheren und (viel schnelleren) Lösung erstellt: http://updates.html5rocks.com/2012/06/How-to-convert-ArrayBuffer-to-and-from- String
Und die Lösung ist:
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
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;
}
EDIT:
Die Encoding API hilft bei der Lösung der String-Konvertierung Problem. Schauen Sie sich die Antwort von Jeff Posnik auf Html5Rocks.com auf den obigen Originalartikel an.
Auszug:
Mit der Encoding-API ist es einfach, zwischen unformatierten Bytes und systemeigenen JavaScript-Zeichenfolgen zu übersetzen, unabhängig davon, mit welcher der vielen Standardcodierungen Sie arbeiten müssen.
<pre id="results"></pre>
<script>
if ('TextDecoder' in window) {
// The local files to be fetched, mapped to the encoding that they're using.
var filesToEncoding = {
'utf8.bin': 'utf-8',
'utf16le.bin': 'utf-16le',
'Macintosh.bin': 'Macintosh'
};
Object.keys(filesToEncoding).forEach(function(file) {
fetchAndDecode(file, filesToEncoding[file]);
});
} else {
document.querySelector('#results').textContent = 'Your browser does not support the Encoding API.'
}
// Use XHR to fetch `file` and interpret its contents as being encoded with `encoding`.
function fetchAndDecode(file, encoding) {
var xhr = new XMLHttpRequest();
xhr.open('GET', file);
// Using 'arraybuffer' as the responseType ensures that the raw data is returned,
// rather than letting XMLHttpRequest decode the data first.
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
if (this.status == 200) {
// The decode() method takes a DataView as a parameter, which is a wrapper on top of the ArrayBuffer.
var dataView = new DataView(this.response);
// The TextDecoder interface is documented at http://encoding.spec.whatwg.org/#interface-textdecoder
var decoder = new TextDecoder(encoding);
var decodedString = decoder.decode(dataView);
// Add the decoded file's text to the <pre> element on the page.
document.querySelector('#results').textContent += decodedString + '\n';
} else {
console.error('Error while requesting', file, this);
}
};
xhr.send();
}
</script>
Sie können TextEncoder
und TextDecoder
aus dem Encoding-Standard verwenden, der durch die stringencoding-Bibliothek polyfill wird, um String in und aus ArrayBuffers zu konvertieren:
var uint8array = new TextEncoder().encode(string);
var string = new TextDecoder(encoding).decode(uint8array);
Blob ist viel langsamer als String.fromCharCode(null,array);
das schlägt jedoch fehl, wenn der Array-Puffer zu groß wird. Die beste Lösung, die ich gefunden habe, ist, String.fromCharCode(null,array);
zu verwenden und sie in Vorgänge aufzuteilen, die den Stack nicht sprengen, aber schneller sind als ein einzelnes Zeichen.
Die beste Lösung für große Arraypuffer ist:
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;
}
Ich fand das etwa 20 mal schneller als mit Blob. Es funktioniert auch für große Saiten mit mehr als 100 MB.
Basierend auf der Antwort von gengkev habe ich Funktionen für beide Arten erstellt, weil BlobBuilder String und ArrayBuffer verarbeiten kann:
function string2ArrayBuffer(string, callback) {
var bb = new BlobBuilder();
bb.append(string);
var f = new FileReader();
f.onload = function(e) {
callback(e.target.result);
}
f.readAsArrayBuffer(bb.getBlob());
}
und
function arrayBuffer2String(buf, callback) {
var bb = new BlobBuilder();
bb.append(buf);
var f = new FileReader();
f.onload = function(e) {
callback(e.target.result)
}
f.readAsText(bb.getBlob());
}
Ein einfacher Test:
string2ArrayBuffer("abc",
function (buf) {
var uInt8 = new Uint8Array(buf);
console.log(uInt8); // Returns `Uint8Array { 0=97, 1=98, 2=99}`
arrayBuffer2String(buf,
function (string) {
console.log(string); // returns "abc"
}
)
}
)
Ich würde empfehlen, nicht zu verwenden
var binaryString = String.fromCharCode.apply(null, new Uint8Array(arrayBuffer));
weil es
Maximum call stack size exceeded
Fehler bei 120000 Byte-Puffer (Chrome 29))Wenn Sie gerade eine synchrone Lösung benötigen, verwenden Sie so etwas
var
binaryString = '',
bytes = new Uint8Array(arrayBuffer),
length = bytes.length;
for (var i = 0; i < length; i++) {
binaryString += String.fromCharCode(bytes[i]);
}
es ist so langsam wie das vorherige, funktioniert aber korrekt. Es scheint, dass es zum Zeitpunkt des Schreibens keine recht schnelle, synchrone Lösung für dieses Problem gibt (alle in diesem Thema genannten Bibliotheken verwenden für ihre synchronen Funktionen den gleichen Ansatz).
Was ich wirklich empfehle, ist die Verwendung von Blob
+ FileReader
function readBinaryStringFromArrayBuffer (arrayBuffer, onSuccess, onFail) {
var reader = new FileReader();
reader.onload = function (event) {
onSuccess(event.target.result);
};
reader.onerror = function (event) {
onFail(event.target.error);
};
reader.readAsBinaryString(new Blob([ arrayBuffer ],
{ type: 'application/octet-stream' }));
}
der einzige Nachteil (nicht für alle) ist, dass es asynchronous ist. Und es ist etwa 8-10 mal schneller als die bisherigen Lösungen! (Einige Details: Eine synchrone Lösung in meiner Umgebung benötigte 950 bis 1050 ms für 2,4 MB Puffer, aber die Lösung mit FileReader hatte etwa 100 bis 120 ms für dieselbe Datenmenge. Und ich habe beide synchronen Lösungen auf 100 Kb Puffer getestet und sie haben fast die gleiche Zeit in Anspruch genommen, so dass die Schleife nicht viel langsamer ist.
BTW hier: Wie konvertiert man ArrayBuffer von und nach String author vergleicht zwei Ansätze wie ich und erhält völlig entgegengesetzte Ergebnisse ( sein Testcode ist hier ) Warum so unterschiedliche Ergebnisse? Wahrscheinlich wegen seiner Test-Saite, die 1 Kb lang ist (er nannte sie "veryLongStr"). Mein Puffer war ein wirklich großes JPEG-Bild mit einer Größe von 2,4 MB.
Im Gegensatz zu den Lösungen hier musste ich UTF-8-Daten konvertieren. Zu diesem Zweck habe ich die folgenden beiden Funktionen mit dem (un) escape/(en) decodeURIComponent-Trick codiert. Der Speicherplatz ist ziemlich verschwenderisch, da die 9-fache Länge der codierten utf8-Zeichenfolge zugewiesen wird. Diese sollten jedoch von gc wiederhergestellt werden. Verwenden Sie sie einfach nicht für 100 MB Text.
function utf8AbFromStr(str) {
var strUtf8 = unescape(encodeURIComponent(str));
var ab = new Uint8Array(strUtf8.length);
for (var i = 0; i < strUtf8.length; i++) {
ab[i] = strUtf8.charCodeAt(i);
}
return ab;
}
function strFromUtf8Ab(ab) {
return decodeURIComponent(escape(String.fromCharCode.apply(null, ab)));
}
Überprüfen, dass es funktioniert:
strFromUtf8Ab(utf8AbFromStr('latinкирилицаαβγδεζηあいうえお'))
-> "latinкирилицаαβγδεζηあいうえお"
(Update Siehe bitte die zweite Hälfte dieser Antwort, wo ich (hoffentlich) eine vollständigere Lösung bereitgestellt habe.)
Ich bin auch auf diese Ausgabe gestoßen, die folgende Arbeit für mich in FF 6 (für eine Richtung):
var buf = new ArrayBuffer( 10 );
var view = new Uint8Array( buf );
view[ 3 ] = 4;
alert(Array.prototype.slice.call(view).join(""));
Leider erhalten Sie natürlich ASCII - Textdarstellungen der Werte im Array und nicht Zeichen. Es sollte (sollte) jedoch noch viel effizienter sein als eine Schleife. Für das obige Beispiel lautet das Ergebnis 0004000000
und nicht mehrere Nullzeichen und ein Chr (4).
Bearbeiten:
Nach einem Blick auf MDChier können Sie eine ArrayBuffer
aus einer Array
wie folgt erstellen:
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;
Um Ihre ursprüngliche Frage zu beantworten, können Sie ArrayBuffer
<-> String
folgendermaßen konvertieren:
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;
}
Der Einfachheit halber ist hier eine function
zum Konvertieren eines unformatierten Unicode String
in eine ArrayBuffer
(funktioniert nur mit ASCII-/1-Byte-Zeichen)
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 ]);
Das obige erlaubt es Ihnen, wieder von ArrayBuffer
-> String
& zurück zu ArrayBuffer
zu gelangen, wo der String zB gespeichert werden kann. .localStorage
:)
Hoffe das hilft,
Dan
Ich habe festgestellt, dass ich Probleme mit diesem Ansatz hatte, im Wesentlichen, weil ich versuchte, die Ausgabe in eine Datei zu schreiben, und diese nicht ordnungsgemäß codiert war. Da JS anscheinend die UCS-2-Codierung ( source , source ) zu verwenden scheint, müssen wir diese Lösung noch einen Schritt weiter ausdehnen. Hier ist meine erweiterte Lösung, die für mich funktioniert.
Ich hatte keine Schwierigkeiten mit generischem Text, aber wenn es sich um Arabisch oder Koreanisch handelte, hatte die Ausgabedatei nicht alle Zeichen, sondern zeigte stattdessen Fehlerzeichen
Dateiausgabe:
","10k unit":"",Follow:"Õ©íüY‹","Follow %{screen_name}":"%{screen_name}U“’Õ©íü",Tweet:"ĤüÈ","Tweet %{hashtag}":"%{hashtag} ’ĤüÈY‹","Tweet to %{name}":"%{name}U“xĤüÈY‹"},ko:{"%{followers_count} followers":"%{followers_count}…X \Ì","100K+":"100Ì tÁ","10k unit":"Ì è",Follow:"\°","Follow %{screen_name}":"%{screen_name} Ø \°X0",K:"œ",M:"1Ì",Tweet:"¸","Tweet %{hashtag}":"%{hashtag}
Original:
","10k unit":"万",Follow:"フォローする","Follow %{screen_name}":"%{screen_name}さんをフォロー",Tweet:"ツイート","Tweet %{hashtag}":"%{hashtag} をツイートする","Tweet to %{name}":"%{name}さんへツイートする"},ko:{"%{followers_count} followers":"%{followers_count}명의 팔로워","100K+":"100만 이상","10k unit":"만 단위",Follow:"팔로우","Follow %{screen_name}":"%{screen_name} 님 팔로우하기",K:"천",M:"백만",Tweet:"트윗","Tweet %{hashtag}":"%{hashtag}
Ich habe die Informationen aus dennis 'Lösung genommen und diesem Beitrag fand ich.
Hier ist mein Code:
function encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
function decode_utf8(s) {
return decodeURIComponent(escape(s));
}
function ab2str(buf) {
var s = String.fromCharCode.apply(null, new Uint8Array(buf));
return decode_utf8(decode_utf8(s))
}
function str2ab(str) {
var s = encode_utf8(str)
var buf = new ArrayBuffer(s.length);
var bufView = new Uint8Array(buf);
for (var i=0, strLen=s.length; i<strLen; i++) {
bufView[i] = s.charCodeAt(i);
}
return bufView;
}
Dadurch kann ich den Inhalt ohne Codierungsprobleme in einer Datei speichern.
Wie es funktioniert: Es benötigt im Wesentlichen die einzelnen 8-Byte-Chunks, aus denen ein UTF-8-Zeichen besteht, und speichert sie als Einzelzeichen (daher kann ein auf diese Weise erstelltes UTF-8-Zeichen aus 1-4 dieser Zeichen bestehen ) . UTF-8 codiert Zeichen in einem Format, das zwischen 1 und 4 Byte lang ist. Was wir hier tun, kodiert den Sting in einer URI-Komponente und nimmt diese Komponente und übersetzt sie in das entsprechende 8-Byte-Zeichen. Auf diese Weise verlieren wir die Informationen nicht, die von UTF8-Zeichen mit einer Länge von mehr als 1 Byte angegeben werden.
Nun, hier ist ein etwas komplizierter Weg, das Gleiche zu tun:
var string = "Blah blah blah", output;
var bb = new (window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder)();
bb.append(string);
var f = new FileReader();
f.onload = function(e) {
// do whatever
output = e.target.result;
}
f.readAsArrayBuffer(bb.getBlob());
Edit: BlobBuilder wurde lange Zeit zugunsten des Blob-Konstruktors abgelehnt, der bei meinem ersten Beitrag nicht existierte. Hier ist eine aktualisierte Version. (Und ja, das war schon immer ein dummer Weg, die Konvertierung durchzuführen, aber es war nur zum Spaß!)
var string = "Blah blah blah", output;
var f = new FileReader();
f.onload = function(e) {
// do whatever
output = e.target.result;
};
f.readAsArrayBuffer(new Blob([string]));
ES2015:
a=Uint8Array.from(s,(x)=>x.charCodeAt(0))
Uint8Array (33) [2, 134, 140, 186, 82, 70, 108, 182, 233, 40, 143, 247, 29, 76, 245, 206, 29, 87, 48, 160, 78, 225, 242 56, 236, 201, 80, 80, 152, 118, 92, 144, 48
s=String.fromCharCode.apply(null,a)
"ºRFl¶é (÷ LõÎW0 Náò8ìÉÉPPv\0"
wenn Sie ein großes Array-Beispiel arr.length=1000000
verwendet haben, können Sie diesen Code verwenden, um Stapelrückrufprobleme zu vermeiden
function ab2str(buf) {
var bufView = new Uint16Array(buf);
var unis =""
for (var i = 0; i < bufView.length; i++) {
unis=unis+String.fromCharCode(bufView[i]);
}
return unis
}
umkehrfunktion Mangini Antwort von oben
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;
}
Nachdem ich mit Manginis Lösung für die Konvertierung von ArrayBuffer
in String
- ab2str
(die die eleganteste und nützlichste ist, die ich gefunden habe - danke!) Gespielt habe, hatte ich einige Probleme beim Umgang mit großen Arrays. Noch spezifischer bewirkt der Aufruf von String.fromCharCode.apply(null, new Uint16Array(buf));
einen Fehler:
arguments array passed to Function.prototype.apply is too large
.
Um es zu lösen (Bypass), habe ich mich entschieden, die Eingabe ArrayBuffer
in Chunks zu behandeln. Die modifizierte Lösung lautet also:
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;
}
Die Blockgröße ist auf 2^16
eingestellt, da dies die Größe ist, die ich in meiner Entwicklungslandschaft gefunden habe. Wenn Sie einen höheren Wert festlegen, wird derselbe Fehler erneut angezeigt. Sie kann geändert werden, indem Sie die Variable CHUNK_SIZE
auf einen anderen Wert setzen. Es ist wichtig, eine gerade Zahl zu haben.
Hinweis zur Leistung - Ich habe für diese Lösung keine Leistungstests durchgeführt. Da es jedoch auf der vorherigen Lösung basiert und große Arrays verarbeiten kann, sehe ich keinen Grund, warum ich es nicht verwenden sollte.
Alle Kommentare sind willkommen (-:
Siehe hier: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays/StringView (Eine C-ähnliche Schnittstelle für Zeichenfolgen, die auf der JavaScript-ArrayBuffer-Schnittstelle basieren)
Der "native" Binärstring, den atob () zurückgibt, ist ein 1 Byte langes Array.
Wir sollten also nicht 2 Byte in einem Charakter speichern.
var arrayBufferToString = function(buffer) {
return String.fromCharCode.apply(null, new Uint8Array(buffer));
}
var stringToArrayBuffer = function(str) {
return (new Uint8Array([].map.call(str,function(x){return x.charCodeAt(0)}))).buffer;
}
Ich habe das benutzt und arbeitet für mich.
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;
}
Ja:
const encstr = (`TextEncoder` in window) ? new TextEncoder().encode(str) : Uint8Array.from(str, c => c.codePointAt(0));
BlobBuilder wurde vom Blob-Objekt seit langem verworfen. Vergleichen Sie den Code in Dennis 'Antwort - wo BlobBuilder verwendet wird - mit dem folgenden Code:
function arrayBufferGen(str, cb) {
var b = new Blob([str]);
var f = new FileReader();
f.onload = function(e) {
cb(e.target.result);
}
f.readAsArrayBuffer(b);
}
Beachten Sie, wie viel sauberer und weniger aufgebläht dies im Vergleich zu der veralteten Methode ist ... Ja, das ist definitiv etwas zu bedenken.
stringToArrayBuffer(byteString) {
var byteArray = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
byteArray[i] = byteString.codePointAt(i);
}
return byteArray;
}
arrayBufferToString(buffer) {
var byteArray = new Uint8Array(buffer);
var byteString = '';
for (var i = 0; i < byteArray.byteLength; i++) {
byteString += String.fromCodePoint(byteArray[i]);
}
return byteString;
}
var decoder = new TextDecoder ();
var string = decoder.decode (arrayBuffer);
Siehe https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/decode