pl: Binary String verarbeiten

hi,

FileReader.readAsBinaryString(blob) gibt mir einen Binary String. Die einzige Möglichkeit die ich gefunden habe um den zu verarbeiten: Byte für Byte durchzugehen um mit escape(byte) an die jeweilige Bytewertigkeit zu kommen. Was diese Funktion auch ganz brav tut bis FF aber nun ist diese Funktion eben auch deprecated und wer weiß wie lange das noch geht.

Das kanns nicht sein. Welche andere Möglichkeiten gibt es zum Verarbeiten eines BinaryString in JS?

Bitte mal um Hinweise. MfG

  1. Tach!

    FileReader.readAsBinaryString(blob) gibt mir einen Binary String. Die einzige Möglichkeit die ich gefunden habe um den zu verarbeiten: Byte für Byte durchzugehen um mit escape(byte) an die jeweilige Bytewertigkeit zu kommen.

    Javascript kennt keinen Datentyp Byte. Der Binärstring, den man da bekommt, ist anscheinend mit Hilfe von außerhalb von Javascript laufendem Code erzeugt worden. Das was in result vom FileReader steht ist jedenfalls ein Javascript-String. Diese enthalten nur Unicode-Zeichen, aber an die Bytes kommt man nicht (direkt). readAsBinaryString() ist aber so clever, dass es byteweise aus der Quelle liest und das entsprechende Zeichen aus dem Unicode-Bereich U+0000..U+00FF in das Ergebnis schreibt. Dessen CodePoint-Nummer kann man ermitteln mit den String-Methoden charCodeAt() oder codePointAt(). Die beiden Methoden sind nicht identisch, ergeben aber in dem Fall dasselbe.

    Das kanns nicht sein. Welche andere Möglichkeiten gibt es zum Verarbeiten eines BinaryString in JS?

    Javascript ist nicht angetreten, um unterhalb von Zeichen und Number zu operieren. Es verbirgt solche Details wie Bytes oder konkrete Repräsentationen à la IEEE 754. Dass man trotzdem an der einen oder anderen Stelle an einige dieser Details rankommen kann, ist der Tatsache geschuldet, dass man das zum Interagieren mit der restlichen Welt braucht. Was auch immer du versuchst, um an die darunterliegende Repräsentation von Daten zu gelangen, ist in meinen Augen ein Arbeiten entgegen der Philosophie von Javascript.

    dedlfix.

    1. Tach!

      FileReader.readAsBinaryString(blob) gibt mir einen Binary String. Die einzige Möglichkeit die ich gefunden habe um den zu verarbeiten: Byte für Byte durchzugehen um mit escape(byte) an die jeweilige Bytewertigkeit zu kommen.

      Javascript kennt keinen Datentyp Byte. Der Binärstring, den man da bekommt, ist anscheinend mit Hilfe von außerhalb von Javascript laufendem Code erzeugt worden.

      FileReader.readAsBinaryString(blob) erzeugt eine Bytesquenz, siehe CODE obenstehend.

      Das was in result vom FileReader steht ist jedenfalls ein Javascript-String.

      Es ist eine Bytesequenz.

      Diese enthalten nur Unicode-Zeichen,

      völlig falsch. Wenn ich meinen Binstring byteweise durchgehe bekomme ich einzelne Bytes mit Wertigkeiten von 0..255. Unicodezeichen hingegen können aus mehreren Bytes bestehen.

      Wie auch immer

      for(i=0;i<bin.length;i++){ console.log( bin[i].codePointAt(), escape(bin[i]) ); }

      liefert mir die richtigen Bytewertigkeiten.

      Javascript ist nicht angetreten, um unterhalb von Zeichen und Number zu operieren.

      Mit diesen Bytewertigkeiten kann ich ein Uint8Array erstellen. Damit einen ArrayBuffer und damit die Grafik wiederherstellen.

      Mit Unicode hat das alles nichts zu tun außer daß Deine Funktion (danke!) hierzu verwendbar ist. MfG

      console

      1. Tach!

        FileReader.readAsBinaryString(blob) erzeugt eine Bytesquenz, siehe CODE obenstehend.

        Nein, typeof theFileReaderInstance.result liefert: string. Das ist in Javascript keine Bytesequenz.

        Das was in result vom FileReader steht ist jedenfalls ein Javascript-String.

        Es ist eine Bytesequenz.

        Nein, typeof theFileReaderInstance.result liefert: string. Das ist in Javascript keine Bytesequenz.

        Diese enthalten nur Unicode-Zeichen,

        völlig falsch.

        Ja, aber mir scheint, dass das Verständnisproblem auf deiner Seite liegt.

        Wenn ich meinen Binstring byteweise durchgehe bekomme ich einzelne Bytes mit Wertigkeiten von 0..255.

        Wie machst du denn das konket, und besonders ohne den nicht existenten Datentyp Byte?

        Man kann auch für Unicode-Zeichen nur die Wertigkeiten 0..255 erhalten, wenn nur Zeichen aus diesem Bereich im String sind.

        Unicodezeichen hingegen können aus mehreren Bytes bestehen.

        Tun sie aber in dem Fall nicht. FileReader.readAsBinaryString() schreibt nur die Zeichen mit den CodePoints 0..255 in das Ergebnis. Das sieht nur aus wie Bytes, ist es aber nicht. Das heißt, aus wievielen Bytes die Zeichen intern bestehen, kannst du sowieso nicht sehen. Du bekommst lediglich irgendwas basierend auf ihrem CodePoint.

        Wie auch immer

        for(i=0;i<bin.length;i++){ console.log( bin[i].codePointAt(), escape(bin[i]) ); }

        liefert mir die richtige Bytewertigkeiten.

        Jein, es liefert die CodePoints der Unicode-Zeichen, die passen aber anderenorts in den Datentyp Byte, weil, wie gesagt, nur die Zeichen mit den CodePoints 0..255 in deinem bin liegen. Damit ist dein Ziel erreicht, aber die Arbeitsweise ist eine andere, als du hier zu erkennen glaubst. Da wird mitnichten byteweise gearbeitet sondern zeichenweise, genauer gesagt mit String mit Inhalt von einem Zeichen. Schau es dir an, was typeof bin[i] liefert: string.

        Javascript ist nicht angetreten, um unterhalb von Zeichen und Number zu operieren.

        Mit diesen Bytewertigkeiten kann ich ein Uint8Array erstellen. Damit einen ArrayBuffer und damit die Grafik wiederherstellen.

        Mit Unicode hat das alles nichts zu tun.

        Oh doch. Das was du außen siehst, kann letzlich nur mit den primitiven Datentypen von Javascript dargestellt werden: String, Number, (und weitere, hier nicht wichtige). Byte ist jedenfalls nicht darunter. Es gibt noch nicht einmal einen eigenen Typ für Zeichen, das ist lediglich ein String mit einem Zeichen Inhalt. String ist jedenfalls eine Sequenz von Unicode-Zeichen. Was es intern ist, ist für Javascript nicht weiter relevant, das sind Implementierungsdetails der jeweiligen Javascript-Engine.

        dedlfix.

        1. Tach!

          Nachtrag:

          for(i=0;i<bin.length;i++){ console.log( bin[i].codePointAt(), escape(bin[i]) ); }

          bin[i].codePointAt() lässt sich auch als bin.codePointAt(i) notieren. Es bleibt sich gleich, ob du einen String der Länge 1 aus einem String an Position i extrahiert und dessen erstes Zeichen untersuchst oder ob du gleich das Zeichen an Position i untersuchst.

          codePointAt() ohne Parameter aufzurufen ist auch nicht definiert. Da findet wohl intern eine Konvertierung von undefined zu 0 statt.

          dedlfix.

        2. Ja, es gibt schon Bytes die sehen in der console aus wie Zeichen. Was den Datentype betrifft: In c verkörpert ein byte einen unsigned integer der einen Wert von 0..255 annehmen kann. Das ist ja auch der Sinn von Datentypen und der Sinn der Typisierung einen ganz bestimmten Wertebereich und damit die Bytelänge festzulegen. Ohne diese Typisierung wäre es gar nicht möglich Daten zu transportieren oder zu speichern. Und in einer Datei ist das Byte die kleinste Speichereinheit.

          Siehe hier wie in c Datentypen transportiert werden.

          Und wenn JS nur Strings kennt ist das eben so. Andere Programmiersprachen unterscheiden ja auch zwischen Strings, Bytesequenzen und Zeichenketten. Immerhin kennt JS ja den BinaryString und ansonsten kennt JS Binärsequenzen (Binaries) auch als Uint8-Array, Blob, File und ArrayBuffer. Und auch hier haben wir als kleinste Speicherinheit wieder das Byte als unsigned integer von 0..255.

          MfG

          1. Tach!

            Ja, es gibt schon Bytes die sehen in der console aus wie Zeichen.

            Andersrum wird ein Schuh draus. In Javascript gibt es keine Bytes und Zeichen als Datentyp. Das was du siehst, sieht nur so ähnlich aus wie anderswo Bytes und Zeichen.

            Was den Datentype betrifft: In c verkörpert ein byte einen unsigned integer der einen Wert von 0..255 annehmen kann.

            Nicht weiter relevant für Javascript. Da gibts nur Number und String, mit denen man das lediglich auf ähnliche Weise abbilden kann.

            Das ist ja auch der Sinn von Datentypen und der Sinn der Typisierung einen ganz bestimmten Wertebereich und damit die Bytelänge festzulegen. Ohne diese Typisierung wäre es gar nicht möglich Daten zu transportieren oder zu speichern. Und in einer Datei ist das Byte die kleinste Speichereinheit.

            Aber was hat das mit Javascript zu tun? Javascript arbeitet nicht auf Transport- oder Speicherebene. Wenn man derartige Funktionalität benötigt, muss man eine der vorhandenen APIs bemühen, die die Aufgabe im Auftrag von Javascript erledigt. Die API-Funktion selbst und die dafür notwendige Konvertierung von und zu den Javascript-Typen läuft außerhalb des Zuständigkeitsbereiches von Javascript.

            dedlfix.

            1. problematische Seite

              Tach!

              Aber was hat das mit Javascript zu tun? Javascript arbeitet nicht auf Transport- oder Speicherebene.

              Da bist Du aber völlig falsch informiert. Siehe FileAPI und selbstverständlich kann man mit JS auch Bytesequenzen lokal speichern und auch transportieren (Ajax).

              Wenn man derartige Funktionalität benötigt, muss man eine der vorhandenen APIs bemühen,

              Vor allem muss man wissen was man will und was man hierzu tun muss. Eine abstrakte Denkweise ist da sehr hilfreich und natürlich die Verbindungen zu anderen Plattformen sowie anderen Programmiersprachen.

              Natürlich gibt es in JS keinen Datentyp byte, genausowenig gibt es einen Solchen in anderen PLs. Aber das Byte ist nunmal die kleinste Speichereinheit und zwar plattformunabhängig. Also auch in JavaScript in Blob, Uint8Array, File sowie ArrayBuffer.

              Wesentlich ist, daß JS ganz ähnlich wie Perl sehr wohl zwischen Zeichenketten und BinaryStrings unterscheidet, siehe hier. Es liegt in der Natur der Dinge daß man gelegentlich was dazulernt. Daß charCodeAt() nicht nur Codepoints von Zeichen liefert sondern die Wertigkeiten beliebiger Bytes war mir neu.

              MfG

              1. problematische Seite

                Tach!

                Aber was hat das mit Javascript zu tun? Javascript arbeitet nicht auf Transport- oder Speicherebene.

                Da bist Du aber völlig falsch informiert. Siehe FileAPI und selbstverständlich kann man mit JS auch Bytesequenzen lokal speichern und auch transportieren (Ajax).

                Die FileAPI macht es, nicht aber Javascript selbst.

                Natürlich gibt es in JS keinen Datentyp byte, genausowenig gibt es einen Solchen in anderen PLs. Aber das Byte ist nunmal die kleinste Speichereinheit und zwar plattformunabhängig. Also auch in JavaScript in Blob, Uint8Array, File sowie ArrayBuffer.

                Mit Verlaub, das betrachte ich als Unsinn. Natürlich kennen andere Sprachen einen Typ für Bytes. Aber nicht alle Plattformen müssen mit Bytes direkt umgehen können. Es gibt nur eine Vielzahl von Systemen, die bytebasiert arbeiten. Das heißt nicht, dass das alle können müssen. Javascript ist dafür ein Beispiel, weil es nicht im Hinblick auf diese konkreten Details entworfen wurde. Es läuft nicht auf einer konkreten Hardware oder einer konkreten Simulation einer Hardware, und kann deshalb losgelöst von diesen Eigenheiten betrachtet werden. Es läuft auf einer Javascript-Engine, und die muss sich um diese Hardwareniederungen kümmern. Ob da auf 8-Bit basierende Technik oder was anderes zum Einsatz kommt, ist aus der Sicht von Javascript nicht weiter relevant.

                Das zeigt sich in der Verfügbarkeit von primitiven Typen. Da gibt es nicht Integer in allen möglichen Varianten und Float/Double, sondern lediglich den sehr generischen Typ Number. Da mag man zwar intern eine Repräsentation der anderswo bekannten Art vorfinden, aber das ist nicht Sache der Sprache Javascript sondern der jeweiligen Engine, die das Javascript ausführt.

                Blob und File sind kein Bestandteil von Javascript. Die gehören zur FileAPI in den Browsern. Man kann sie lediglich mit Javascript ansprechen, aber auch nur im Rahmen der primitiven Typen von Javascript.

                Uint8Array und dessen Geschwister sind zwar Built-in-Objekte, das heißt aber nicht, dass die zwingend mit solchen Typen arbeiten. Ein Uint8Array ist lediglich die Repräsentation eines Arrays, das tut zumindest so, als ob es ein solches Array wäre. Man bekommt jedoch weiterhin nur Werte von Typ Number zu Gesicht, wenn man auf dessen Elemente zugreift. Ob es intern mit solchen Werten arbeitet ist nicht zwangsläufig gesagt.

                Wesentlich ist, daß JS ganz ähnlich wie Perl sehr wohl zwischen Zeichenketten und BinaryStrings unterscheidet

                Für mich ist wesentlich, zwischen Javascript an sich und über APIs ansprechbare Dinge zu unterscheiden.

                dedlfix.

                1. problematische Seite

                  hi @dedlfix

                  das Byte ist die kleinste Speichereinheit in Dateien. Darauf kommt es an. So werden Dateien byteweise oder in Blöcken von Bytes gelesen und verarbeitet. Wenn man also im Vorab weiß wieviele Bytes zu lesen sind, liest man einen Block (Binärdateien).

                  Und genau deswegen sind Textdateien stets weniger performant zu verarbeiten weil da jedes einzelne Byte untersucht werden muss.

                  MfG

                  1. problematische Seite

                    Hallo pl,

                    Und genau deswegen sind Textdateien stets weniger performant zu verarbeiten weil da jedes einzelne Byte untersucht werden muss.

                    Genau. Deshalb werden ja auch kaum noch irgendwelche HTML- oder JavaScript-Dokumente als Text geschrieben. Wär ja blöd, wenn das auch noch jeder lesen könnte.

                    Bis demnächst
                    Matthias

                    -- Pantoffeltierchen haben keine Hobbys.
                    1. problematische Seite

                      Jeder Texteditor muß Dateien byteweise lesen. Sonst kann er ja die Zeichen nicht darstellen.

                      MfG

                      1. problematische Seite

                        Tach!

                        Jeder Texteditor muß Dateien byteweise lesen. Sonst kann er ja die Zeichen nicht darstellen.

                        Das kommt darauf an, wie du Texteditor definierst. Für ein eigenständiges Programm, das als eine seiner Aufgaben auf Dateien auf Speichermedien zugreift, ist diese Aussage richtig. Wenn du hingegen eine <textarea> von HTML nimmst, in der man ebenso Text editieren kann, dann spielen Bytes keine Rolle. Da kommt "Text" rein und geht "Text" raus. Was dabei im Hintergrund und in der weiteren Verarbeitung passiert, ist für die Webseite mit ihrer Textarea nicht sichtbar, nicht beeinflussbar, und damit auch nicht relevant, ob da Bytes oder was anderes als Grundlage dient.

                        dedlfix.

                      2. problematische Seite

                        Hallo pl,

                        ja, muss er. Und? Wir sprachen von JavaScript.

                        BTW:

                        Natürlich gibt es in JS keinen Datentyp byte, genausowenig gibt es einen Solchen in anderen PLs.

                        Das ist falsch. C, C++, C# und Java kennen einen byte-Datentyp (in C/C++ als char oder unsigned char, in C# als byte oder signed byte, in Java als byte), der als 8-bit Wert definiert ist. D.h. ein char[] in C oder ein byte[] in C#/Java belegt ein Byte pro Element.

                        Bei einem Uint8Array in JavaScript ist das - soweit ich das bei Tante Google erfahren konnte - genauso.

                        Was ich aber auch gefunden habe, ist, dass die V8 Engine in Chrome 1-byte und 2-byte Strings kennt. D.h. es ist möglich, dass dein "readAsBinaryString" tatsächlich einen String mit einem Byte pro Zeichen liefert. Das sollte Dir als JS Programmierer aber egal sein, du kannst erwarten dass die JS Engine das vor Dir versteckt.

                        Damit nochmal zu deiner Ausgangsfrage:

                        [escape() ist deprecated] Welche andere Möglichkeiten gibt es zum Verarbeiten eines BinaryString in JS?

                        charCodeAt hast Du ja mittlerweile gefunden. Aber das, was Du in deinem Artikel beschreibst, ist nach wie vor irreführend. charCodeAt liefert den Code eines ZEICHENS in einem String. Ein String in JavaScript ist LAUT SPEC als UTF-16 codiert, nicht UTF-8. Diese Umcodierung passiert nur dann, wenn Du ihn in einen Blob steckst, weil UTF-8 im Web die Standardcodierung für Unicode-Strings ist. Und readAsBinaryString erzeugt aus dem Blob dann einen String, der aus jedem Byte genau ein Zeichen macht, ohne Rücksicht darauf, ob die Bytesequenz im Blob einen String in einem bestimmten Encoding darstellt oder nicht. DIESER String ist wiederum in der JavaScript-Darstellung für Strings gespeichert, laut Spec also mit 2 Bytes pro Zeichen, laut Aussage aus der Quelle oben ggf. auch technisch optimiert auf 1 Byte pro Zeichen. Das ist aber rein intern. Ich habe folgendes gemacht:

                        b = new Blob(["äöü"]); // -> Blob(6) { size: 6, type: "" } fr = new FileReader(); fr.readAsBinaryString(b); bs = fr.result; // -> "äöü" b2 = new Blob([bs]); // -> Blob(12) { size: 12, type: "" }

                        Das war im Chrome-Debugger, also mit V8. D.h. der Binary String wird bei erneuter Blobifizierung erneut UTF-8 codiert und verdoppelt seine Länge (weil alle Bytewerte jenseits der 127 liegen). Selbst WENN Chrome fr.result intern als einbytigen String gespeichert hätte, er fasst die Bytewerte immer noch als Unicode-Codepoints im Intervall [0..255] auf.

                        Du kannst den von readAsBinaryString gelieferten String also durchaus benutzen, um die Wertigkeiten der Bytes im Blob zu ermitteln. Auf der Abstraktionsebene von JavaScript enthält dieser String aber keine Bytes. Sondern Zeichen.

                        Vermeiden kannst Du dieses Verwirrspiel nur, wenn Du readAsArrayBuffer verwendest, einen DataView darauflegst und die get/set Methoden für Uint8 verwendest.

                        Rolf

                        -- sumpsi - posui - clusi
                        1. problematische Seite

                          hi @Rolf B

                          die Funktion liefert mir die richtigen Bytewertigkeiten. Du musst mir also nicht erzählen was falsch und richtig ist oder was geht und was nicht. Den Binary String brauche ich für einen ganz bestimmten Verwendungszweck und davon ist die Verwirklichung einiger Programmierideen abhhhängig.

                          Und über Datentypen müssen wir hier auch nicht diskutieren, wir sind doch beide lang genug dabei. Entscheidend ist, wie man einen String bytesemantisch verwendet. Und für meine Verwendung ist es entscheidend daß es ein String ist und eben nicht ein Blob oder ArrayBuffer.

                          Arraybuffer to String und umgekehrt, das sind meine neuen Funktionen und die arbeiten nicht zeichen- sondern byteorientiert. Mein Artikel erkärt den Unterschied.

                          MfG

                          1. problematische Seite

                            Hallo pl,

                            kein Minus von mir, das waren andere.

                            Wenn Du mir nicht glauben willst, dann vielleicht der MDN?

                            Note that this method was once removed from the File API specification, but re-introduced for backward compatibility.
                            Using FileReader.readAsArrayBuffer() is recommended.

                            readAsBinaryString ist überhaupt nur noch im API, weil es zu viele - mangels besserer verfügbarer Techniken - genutzt haben.

                            Wenn Du den binary string für die weitere Verarbeitung brauchst, wäre in der weiteren Verarbeitung möglicherweise eine Replanung fällig.

                            Rolf

                            -- sumpsi - posui - clusi
  2. Hallo pl,

    FileReader.readAsBinaryString(blob) gibt mir einen Binary String.

    damit bist Du, wenn Du den Blob byteweise verarbeiten willst, schon ganz zu Anfang falsch abgebogen.

    Korrekt wäre readAsArrayBuffer, und auf den legst Du ein Uint8Array. Und über das Uint8Array kannst Du dann per [] Operator auf die einzelnen Bytes als numbers zugreifen. Der Uint8Array Konstruktor könnte allerdings den ArrayBuffer kopieren und damit bei großen Blobs viel Speicher verputzen.

    Alternativ legst Du auf den ArrayBuffer einen DataView und verwendest die get/setUint8 Methoden. Der DataView kopiert definitiv nicht.

    Rolf

    -- sumpsi - posui - clusi
    1. @Rolf B

      ist doch schön mit Dir zu plaudern.

      FileReader.readAsBinaryString(blob) gibt mir einen Binary String.

      damit bist Du, wenn Du den Blob byteweise verarbeiten willst, schon ganz zu Anfang falsch abgebogen.

      Richtig! Aber mir gehts gar nicht darum, nur Blobs an sich zu verarbeiten. Vielmehr dreht sich alles nur um einen String und Bytesemantic. Die Quelle für den String kann ein Blob//File sein, muss aber nicht. Die Quelle kann und wird auch ein ArrayBuffer sein.

      Meine Anwendung wird also Mehreres können, die Daten per Ajax anfordern, zum Speicher unter anbieten, lokal im Browser speichern und von Diskette (HDD, USB) wieder einspielen in die SPA.

      Es wird eine Multimediadatei sein womit man mehrere HTML Seiten mit eingebetteten Grafiken lokal im Browser darstellen kann. Also die Datei speichert bzw. transportiert alles zusammen, sowohl html als auch Grafiken.

      Diese Datei also wird ein paar MBchen haben und über die Anwendung hinweg als String, Blob, Uin8Array oder ArrayBuffer metamorphieren.

      Das wird also richtig schön komplex. MfG

  3. problematische Seite

    Nun, Grund genug für einen kleinen Artikel welcher den ganzen Sachverhalt mal deutlich macht. Also wie JS, ganz ähnlich wie Perl, zwischen Bytesequenzen und Zeichenketten unterscheidet.

    Man muss nur richtig damit umgehen.

    MfG

    1. problematische Seite

      Tach!

      Nun, Grund genug für einen kleinen Artikel welcher den ganzen Sachverhalt mal deutlich macht. Also wie JS, ganz ähnlich wie Perl, zwischen Bytesequenzen und Zeichenketten unterscheidet.

      Das was du da siehst, sehe ich nicht. Du erzeugst aus einem String ein Blob-Objekt, das du dann weiterverarbeitest (mit der Methode FileReader.readAsBinaryString(), die eigentlich abgeschafft werden sollte und nur wegen Kompatibilität noch ein Gnadenbrot bekommt).

      Zitat MDN zu Blob: A Blob object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format.

      Die FileAPI-Spezifikation weiß dazu auch noch "A Blob object refers to a byte sequence".

      Da gibt es also das Blob-Objekt aus der FileAPI, das ein Hilfsmittel ist, um mit Bytesequenzen umgehen zu können. "Javascript unterscheidet zwischen Bytesequenzen und Zeichenketten" ist da keine Aussage, die ich daraus lesen könnte. Vielmehr kennt Javascript nach wie vor keine Bytes als Typ. Es kommt lediglich da, wo die FileAPI zur Verfügung steht, die Möglichkeit hinzu, mit Bytesequenzen umgehen zu können.

      dedlfix.

    2. problematische Seite

      Hallo pl,

      Anmerkung: Die Funktion charCodeAt() liefert die Wertigkeiten beliebiger Bytes.

      In deinem speziellen Fall ja. Im allgemeinen: Nein. Gegenbeispiel:

      let a = "17€"; console.log(a.charCodeAt(2)); // -> 8364

      Das ist kein Byte. Das ist ein Unicode-Zeichen. Unicode-Zeichen sind keine Bytes. Ein Unicodezeichen wird durch einen numerischen Wert im Intervall von 0 bis 0x10ffff repräsentiert. Je nach verwendetem Encoding wird daraus dann die eine oder andere Bytekette, wenn ein String aus Unicodezeichen in eine Bytesequenz umzuwandeln ist.

      Und wie dedlfix schon erklärte: readAsBinaryString erzeugt KEINE Bytesequenz. this.result im onload Handler ist ein String, der 6 Unicodezeichen mit Codewerten im Beweich von 0 bis 255 enthält. Ob die Zeichen Bytes sind, oder Worte, oder Doppelworte, das ist ein Implementierungsdetail der JavaScript Engine. Aber vermutlich ist es NICHT ein Byte pro Zeichen, sondern 2.

      Deswegen - wie ich schon schrieb - ist readAsBinaryString nicht das geeignete Werkzeug, um einem Blob byteweise zu verarbeiten. Du hättest besser meine Antwort bezüglich Uint8Array oder DataView gelesen, bevor Du deinen Artikel geschrieben hast.

      Rolf

      -- sumpsi - posui - clusi
      1. problematische Seite

        hi @Rolf B

        Anmerkung: Die Funktion charCodeAt() liefert die Wertigkeiten beliebiger Bytes.

        In deinem speziellen Fall ja. Im allgemeinen: Nein. Gegenbeispiel:

        let a = "17€"; console.log(a.charCodeAt(2)); // -> 8364

        Das ist kein Byte. Das ist ein Unicode-Zeichen.

        Genau. Weil Du eben nicht mit Bytes operierst sondern mit Zeichen. Mein Artikel erklärt ja den Unterschied.

        Deswegen - wie ich schon schrieb - ist readAsBinaryString nicht das geeignete Werkzeug, um einem Blob byteweise zu verarbeiten.

        Das behauptet ja auch keiner. Die Binary kann ich nämlich auch anders erzeugen. Den Filereader und readAsBinaryString brauche ich dazu nicht unbedingt. Nurmalso als Hintergrund: Es sind mehrere Plattformen im Spiel, es geht sowohl um den Transport als auch um das Speichern. Aber mein Plan steht ja bereits.

        MfG

        1. problematische Seite

          hi @Rolf B

          Anmerkung: Die Funktion charCodeAt() liefert die Wertigkeiten beliebiger Bytes.

          In deinem speziellen Fall ja. Im allgemeinen: Nein. Gegenbeispiel:

          let a = "17€"; console.log(a.charCodeAt(2)); // -> 8364

          Das ist kein Byte. Das ist ein Unicode-Zeichen.

          Genau. Weil Du eben nicht mit Bytes operierst sondern mit Zeichen. Mein Artikel erklärt ja den Unterschied.

          Du müsstest also, um bytesemantisch arbeiten zu können, aus der Zeichenkette einen Blob erzeugen:

          blob = new Blob(['17€']);

          Und wenn Du den Blob dann als BinaryString hast, hat der eine Länge von 5 Byte. Und siehe da, der index [2] zeigt da nicht auf das 3. Zeichen sondern auf das 3. Byte mit der Wertigkeit E2 (226 dezimal) also das erste zum Eurozeichen gehörige Byte.

          MfG

  4. problematische Seite

    Hi,

    dank Eurer fleißigen Mitarbeit erlaube ich mir, Euch eine kleine Anwendung vorzustellen.

    localStorage wird benutzt zum Speichern von HTML+Images dank Binary String. So kann die Seite samt Bildern jedrzeig wiederhergestellt werden ohne daß die Daten neu vom Server geholt werden müssen. Der BinaryString dient also dem Transport und der Speicherung, alles in Einem.

    Bitte mal gucken ob der neueste IE da mitspielt. In FF und Chrome tuts bei mir.

    MfG

    1. problematische Seite

      Tach!

      localStorage wird benutzt zum Speichern von HTML+Images dank Binary String. So kann die Seite samt Bildern jedrzeig wiederhergestellt werden ohne daß die Daten neu vom Server geholt werden müssen.

      Um Serverzugriffe zu sparen, hat man den Cache im Browser erfunden.

      dedlfix.

    2. problematische Seite

      Hab nochn bissl was dazugechrieben:

      Die Idee, sämtliche Inhalte, HTL und Multimedia, als nur eine einzige Datei auszuliefern ist nicht neu. Die hier vorgestellte Anwendung verfolgt diese Idee insofern, als daß eben diese Inhalte in einer einzigen Datei ausgeliefert und diese Datei lokal gespeichert wird. Es ist nur so, daß der HTML Standard eben noch nicht soweit entwickelt ist wie zum Beispiel PDF was das Ausliefern und den Transport eingebetteter Inhalte wie Grafiken und Schriftarten in einer Datei ermöglicht…

      Viel Spaß weiterhin und danke für Rükmeldungen!

      1. problematische Seite

        Hallo pl,

        bisher war's ja nur eine akademische Übung...

        Im IE11 passiert beim Laden nix, bzw. nachher sagt er es wäre nichts da. In der Konsole erscheint keine Meldung. Habe jetzt aber keine Zeit zum Debuggen.

        Der kleine a-bär brummt jedoch. Eingebettete Inhalte löst man - wie Du weißt - per Data-URL und ansonsten gibt's noch HTTP/2 für eine requestärmere Übertragung.

        Und welchen Use-Case siehst Du für diese Anwendung, die vom Browser-Cache nicht erfüllt werden kann?

        Ich bin ab jetzt für's Wochenende weg, kann also nicht weiter diskutieren.

        Rolf

        -- sumpsi - posui - clusi
        1. problematische Seite

          hi @Rolf B

          Und welchen Use-Case siehst Du für diese Anwendung, die vom Browser-Cache nicht erfüllt werden kann?

          Es geht in Richtung SPA. Also nicht nur darum eine Seite aus dem Cache zu holen sondern einige hundert Seiten samt Multimedialer Inhalte von Lokal zu laden und darüber zu navigieren.

          Was DataURL betrifft: Base64 vergrößert die Binary. Und da für viele Seiten ohnehin serialisiert werden muss, wird eben binary safe serialisiert was Base64 überflüssig macht.

          MfG

          1. problematische Seite

            Tach!

            Und welchen Use-Case siehst Du für diese Anwendung, die vom Browser-Cache nicht erfüllt werden kann?

            Es geht in Richtung SPA. Also nicht nur darum eine Seite aus dem Cache zu holen sondern einige hundert Seiten samt Multimedialer Inhalte von Lokal zu laden und darüber zu navigieren.

            Anders als beim Browser-Cache hat der LocalStorage kein Verfallsdatum. Die Daten dort bleiben drin liegen, auch wenn sie ewig nicht aufgerufen wurden.

            "einige hundert Seiten samt Multimedialer Inhalte"? Dir ist bewusst, dass die Größe des LocalStorage begrenzt ist. Die Empfehlung lautet 5 MB pro Domain. Der Cache ist deutlich größer und lässt alten Mist ohne weiteres Zutun des Anwenders verschwinden.

            dedlfix.