Hallo pl,
Es sind nur 8 Bit (1 byte), nicht 16
Falsch.
var s = String.fromCharCode(195,164,228); console.log(s, s.length); // siehst Du // ää 3
Ich sehe, dass der String 3 Zeichen enthält. Und ich weiß, dass diese Zeichen JS-intern 16-bittig gespeichert werden.
Das, was passiert wenn Du diesen String in einen Blob legst und ihn per FileReader und seine UTF-8 Codierung mit readAsBinaryString abholst, hat damit nichts zu tun.
.length ist also die Anzahl der bytes die dabei rauskommen.
Nein. Die Anzahl der Zeichen.
Ob JS intern da mit 2 byte je byte operiert (UTF16) ist mir vollkommen egal.
Schade. Weil genau das das Thema dieser Diskussion ist.
Ich habe hier Binaries im MB Bereich und die sind absolut bytegenau.
Sie werden bytegenau als ein Zeichen pro Byte gespeichert. D.h. der „binary string“, den Du aus deinem Binary erhältst, belegt doppelt so viele Bytes wie dein Binary. Das kann Dir egal sein solange es nur ein paar MB sind; es kann Dir nicht egal sein, wenn der Browser 32-bittig läuft und Du in den Bereich von hunderten von MB kommst.
PS: Die eigentliche Frage warum JS mit
String.fromCharCode(195,164)
kein ä zeigt ist übrigens immer noch offen.
Nein. Du gibst ihm zwei Bytes eines UTF-8 Encodings, aber führst die Decodierung dieses Encodings nicht durch. Statt dessen bekommst Du gemäß Spec ein JavaScript-Objekt, in dem sich neben Verwaltungsinformationen 4 Bytes mit den Werten 195,0,164,0 befinden (auf einer little-endian Maschine). Es ist ein String in UTF-16 Codierung. Wenn Du UTF-8 decodieren willst, gibt es den TextDecoder, der aber nicht überall verfügbar ist, manuelles Gefummel mit Escape/Unescape-Techniken oder manuelle Interpretation des Encodings (wie Du es schon gezeigt hast). Manuelle Methoden kannst Du auch indirekt anwenden, mittels geeigneter JS Libraries (mutmaßlich StringView.js).
Rolf
sumpsi - posui - clusi