FFFE aus Datei auslesen (beide Byte am Anfang)

  • ein ganz herzliches . . . hallo

    eine datei in ANSI/DOS sieht so aus
    [Blockierte Grafik: http://www.aaoo.info/musterdatei_ANSI.jpg]


    eine datei in UTF-8 sieht so aus (beginnt immer mit FFFE)
    [Blockierte Grafik: http://www.aaoo.info/musterdatei_UTF-8.jpg]


    lade ich die datei mit FileOpen(), so stehen mir die beiden byte am anfang nicht zur verfügung.

    diese möchte ich aber unbedingt abfragen/auslesen und nicht via FileGetEncoding()

    wer weiss konkreten rat ? danke

  • eine datei in UTF-8 sieht so aus (beginnt immer mit FFFE)

    Meines Wissens nach ist dies das Byte-Order-Mark von UTF-16 Little-Endian.

    Diese Marks werden nur gesetzt wenn du explizit das Byte-Order-Mark mit speichern möchtest (das ist immer mit "BOM" gemeint).
    Bei UTF-8 wäre das BOM im Übrigen "EF BB BF". Aber eine Pflicht es zu setzen gibt es nicht.
    In den von dir angehangen Dateien wurde dies auch anscheinend unterlassen.
    Denn dort gibt es kein BOM.

    Anyway: Auslesen könntest du es (so es denn existiert) in AutoIt so:

    AutoIt
    $hFile = FileOpen("musterdatei_UTF-8.txt", 16)
    $s_First2Bytes = FileRead($hFile, 2)
    FileClose($hFile)
    MsgBox(0,"", "Die ersten 2 Bytes: " & Hex($s_First2Bytes))
  • Wo ignoriert es "FFFE"?
    Die Dateien, welche du angehangen hast, enthalten wie gesagt kein "FFFE" (Siehe Hexeditor).
    Speichere ich korrekt eine Datei als UTF-16 LE mit BOM wird mir mit obigen Code auch korrekt "FFFE" zurück gegeben.

    Einmal editiert, zuletzt von AspirinJunkie (18. August 2015 um 10:27)

  • hallo lieber AspirinJunkie

    verhedere dich nicht mit den Bezeichnungen wie UTF-16 Little Ending.
    das alles interessiert nicht was wie eine Datei ggf sein soll/könnte.

    das "Thema" sagt es.
    es geht schlicht und einfach darum, die echten ersten beiden Byte aus einer Datei zu lesen.
    egal ob bild, text, oder sonst etwas.

    mein editor (ultraedit) zeigt alles an. nicht aber jeder editor kann/will das.

    in der datei musterdatei_ANSI.txt ist FFFE nicht enthalten und in der datei
    musterdatei_UTF-8.txt ist FFFE enthalten und ebenso zu jedem zeichen noch ein Byte
    mit 00. das siehst du auch an der echten grösse der datei.

    nur wenn du das siehst kannst du weiterhelfen.

  • hallo zusammen
    kann man nicht mit FileCopy() die Textdatei, die Probleme macht einfach kopieren als/in eine Bilddatei
    und so FileOpen() quasi überlisten. In einer Bilddatei werden ja sicher die Byte von anfang an eingelesen.

  • verhedere dich nicht mit den Bezeichnungen wie UTF-16 Little Ending.
    das alles interessiert nicht was wie eine Datei ggf sein soll/könnte.

    Keine Angst ich verheddere mich da nicht.
    Und doch - es interessiert durchaus.
    Bei UTF-8 wären die zusätzlichen Nullen nicht da (und auch das FFFE am Anfang).
    Das Bild der zweiten Datei zeigt also tatsächlich eine UTF-16 LE Datei und keine UTF-8-Datei.
    Die gepostete Datei zum Herunterladen ist hingegen eine UTF-8 ohne BOM (also ohne "EF BB BF" am Anfang).

    mein editor (ultraedit) zeigt alles an. nicht aber jeder editor kann/will das.

    Habe mir auch extra nochmal UltraEdit runtergeladen und installiert. Die Dateien nochmals heruntergeladen und wie gesagt: Auch Ultra-Edit meldet keinerlei FFFE. Sowohl in der normalen Ansicht als auch in der HEX-View.
    Das Texteditoren das BOM (wenn sie denn UTF-Unterstützung bieten) nicht anzeigen ist klar. Deswegen schrieb ich das man einen Hex-Editor zur Hilfe nehmen soll. Denn dieser schert sich nicht um Unicode-Marker sondern behandelt eine Datei nur als Ansammlung von Bytes (genauso wie das FileOpen oben mit dem Flag 16).
    In den von dir hochgeladenen Dateien existiert das BOM schlicht und einfach nicht.
    Lad sie am besten selbst noch einmal runter und schaue Sie dir in einem HEX-Editor deiner Wahl an (z.B. den von Ultra-Edit). Dabei aber darauf achten nicht zwischenzuspeichern (denn das könnte bei entsprechend gesetzter Formatierung das BOM noch hinzufügen).

    das siehst du auch an der echten grösse der datei.

    Die Dateien (zumindestens diese welche man hier herunterladen kann) unterscheiden sich in exakt 4 Bytes.
    Wenn es wie in deinem Bild dargestellt zwei Bytes pro Zeichen wären, wäre die zweite Datei doppelt so groß.
    Ist sie aber nicht.

    Im UltraEdit muss man übrigens aufpassen bei der HEX-Ansicht nicht "HEX Edit/EBCDIC" zu verwenden sondern nur den normalen Hex-Edit.
    Beim ersten wird der Inhalt zur Darstellung in EBCDIC konvertiert. Dann sieht es so aus wie oben in deinem zweiten Bild.
    Mit dem eigentlichen Inhalt der Datei hat das aber nichts zu tun - es ist nur zur Darstellung im Editor konvertiert.


    Vielleicht nochmal ein paar grundlegende Basics:

    eine datei in UTF-8 sieht so aus (beginnt immer mit FFFE)

    Eine UTF-8 Datei beginnt nie mit FFFE. Nur UTF-16 Dateien in Little-Endian mit gesetztem BOM beginnen so.
    UTF-8 Dateien können direkt mit dem Text beginnen oder mit dem Byte-Order-Mark von UTF-8 und dieses ist bei UTF-8 eben "EF BB BF" und nicht FFFE.
    Zusammengefasst: Es ist keine Pflicht (und auch kein Quasi-Standard) das eine UTF-8-Datei mit einem BOM beginnt.
    Nur anhand der ersten zwei Bytes kann man also nie mit Sicherheit UTF-8 erkennen weil das BOM eben optional ist.

    3 Mal editiert, zuletzt von AspirinJunkie (18. August 2015 um 13:13)

  • AspirinJunkie hat (wie immer) Recht!

    Fileread("dateiname.bla") ist es herzlich egal, in welchem Format eine Datei vorliegt, es werden BYTES eingelesen!
    //EDIT falsch, Fileread(Dateiname) konvertiert beim Einlesen!, daher sollte FileOpen(Dateiname,16) zum Einlesen in Binary genutzt werden.

    Wer mag, kann erst FileOpen() nutzen, sollte dann aber tunlichst auf den Modus achten, ansonsten passieren nämlich die vom TE festgestellten "Fehler".

    Im UltraEdit muss man übrigens aufpassen bei der HEX-Ansicht nicht "HEX Edit/EBCDIC" zu verwenden sondern nur den normalen Hex-Edit.

    was der Grund ist, wieso ich seit Jahrzehnten nur "einfachste" Hexeditoren nutze! Nichts ist schlimmer, als von unrichtigen Vorgaben auszugehen!

    //EDIT2
    Testscript

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    3 Mal editiert, zuletzt von Andy (18. August 2015 um 14:55)

  • Fileread("dateiname.bla") ist es herzlich egal, in welchem Format eine Datei vorliegt, es werden BYTES eingelesen!

    Eigentlich nicht ganz... ;)
    Wenn man z.B. eine UTF-16 mit BOM ohne FileOpen() mit FileRead() ausliest wird erst intern die Kodierung gecheckt und in diesem Fall dann als UTF-16 LE erkannt.
    Das führt dann dazu, dass tatsächlich das BOM (FF FE) übersprungen wird (und es werden 2 Byte pro Zeichen gelesen statt 1).
    Deswegen (wie du ja auch schriebst) um sicher zu gehen: FileOpen mit Flag 16 und alles ist gut.

    Aber kann ich deinen Post als unabhängige Bestätigung ansehen, dass die herunterladbaren Dateien des TE tatsächlich kein BOM enthalten?

  • hallo
    es geht wie mir scheint nicht um den Editor, oder doch.
    habe beide Dateien abgeholt und sie entsprechen dem was Supernova bebildert hat.
    bei meinem Ultraedit geht das schon immer bestens.
    hingegen beim allseit sehr beliebten Notepad++ kann man die HEX mit einem Addon ansehen.
    da allerdings fehlt auch FFFe
    [Blockierte Grafik: http://www.aaoo.info/notepadPP.jpg]

    -
    ebenso denke ich geht es nicht um den typ/Zeichensatz etc. einer Datei, oder doch.

    jedenfalls liest die _WinAPI_ReadFile() [ist ja beinahe schon LowLevel] den Vorspann auch nicht
    und zeigt erst ab dem 3. Byte an.

    AutoIt
    global $tBuffer,$hFile,$iSize,$nBytes,$sText
    $tBuffer=DllStructCreate("byte[6]")
    $hFile=_WinAPI_CreateFile(@ScriptDir & "musterdatei_UTF-8.txt",2,2)
    $iSize=_WinAPI_GetFileSizeEx($hFile)
    _WinAPI_SetFilePointer($hFile,0)
    _WinAPI_ReadFile($hFile, $tBuffer,6,$nBytes)
    _WinAPI_CloseHandle($hFile)
    $sText=BinaryToString(DllStructGetData($tBuffer,1))
    ConsoleWrite($iSize & '|' & $sText & "|" & @CRLF & @CRLF)

    irgendwie müsste man doch ohne wenn und aber eine Datei 1:1 einlesen können!

  • Eigentlich nicht ganz...

    nimm mal die 3.3.6.1....man sollte bei aktuellen Diskussionen die aktuellen Versionen nutzen!
    Habe meinen Post editiert, incl. Testscript.

  • hallo zusammen

    den trick/vorschlag von wir4all mit dem "umkopieren" von einer textdatei in eine bilddatei und erst dann diese mit FileOpen() öffnen hat nichts gebracht. dieser trick geht leider nicht.

    gango hat recht. das format der datei interessiert überhaupt nicht. man sollte einfach die möglichkeit
    haben eine datei, egal was, vom echten anfang bis zum echten ende einlesen zu können.

    vielleicht bringt es uns weiter, wenn wir annehmen es sei eine simple EXE-datei die wir byte für byte
    einlesen möchten, ob in eine variable oder array ist egal.

  • irgendwie müsste man doch ohne wenn und aber eine Datei 1:1 einlesen können!

    Funktioniert einwandfrei mit FileOpen() im Binary-Modus 16!

    Übrigens liest auch FileRead("Datei.exe") ein EXE-File problemlos mit allen Bytes ein!
    Das "UTF-Textdatei-Syndrom" tritt auf, weil AutoIt´s FileRead() den Dateiinhalt analysiert und "automatisch" konvertiert!
    s.Testscript in Post 9

  • upps!!!

    schade dass es kein trick war.
    habe bereits mit einem bravo gerechnet und die gläser für den schamppus bereitgestellt.
    okay.

    vielleicht hilft aber StdoutRead() weiter.

  • es geht wie mir scheint nicht um den Editor, oder doch.
    habe beide Dateien abgeholt und sie entsprechen dem was Supernova bebildert hat.

    Wenn es so wäre wie bebildert hätten die beiden Dateien keine Größendifferenz von nur 4 Byte sondern von mehr als 30 Byte.
    Sieht man ja auch sehr schön im Bild. Dort werden 60 Bytes angezeigt. Die Größe der hochgeladenen Datei ist aber 32 Bytes.
    Die im Bild dargestellte Datei kann also gar nicht die hier hochgeladene Datei sein.

    Da du ebenfalls Ultra-Edit verwendest riecht es daher stark nach einer impliziten Konvertierung innerhalb Ultra-Edits.
    Ein reiner Hex-Editor zeigt die Datei an wie sie ist - definitiv ohne implizite Konvertierung.

    Nehmt einfach eine Textdatei mit irgendeinem Text und speichert diese explizit als UTF-16 LE mit BOM (z.B. mit Notepad++, Notepad2, Sublime Text etc.).
    Diese Datei dann mit dem obigen Code auslesen und es wird korrekt 0xFFFE zurück gegeben.
    Weil das BOM dann auch tatsächlich in der Datei steht.
    Im Gegensatz zu den hier hochgeladenen Dateien.

    nimm mal die 3.3.6.1....

    Ah ok - gut zu wissen woran es lag.

    hier das Ergebnis wenn man die datei mit FileOpen() und dem mode=16 einliest.


    [...Bild...]


    FFFE fehlt.

    Und nicht nur FFFE - auch die ganzen Zwischennullen.
    Könnte es vielleicht nicht doch zufällig daran liegen dass diese Datei nicht der Bilddarstellung entspricht weil dieses auf der implizite Konvertierung innerhalb Ultra-Edits beruht?...
    Wie gesagt: Auch Ultra-Edit zeigt mir keinerlei FFFE an.
    Erst wenn ich auf HEX-View/EBCDIC switche.

    Einmal editiert, zuletzt von AspirinJunkie (18. August 2015 um 15:35)

  • Man sollte den DEV´s mal auf den Hut hauen....

    Wäre echt mal interessant zu wissen, auf welcher Grundlage ein UTF8 innerhalb einer Datei "konvertiert" wird!

    //EDIT
    Wenn ein LF (0x0A) vor dem UTF-Code steht, wird "transmutiert"^^
    //EDIT2 wenn der Code "valide" UTF-Texte (als Kodierung) beinhaltet, wird automatisch dekodiert

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (18. August 2015 um 16:01)

  • ;3.versuch nur die letzten 5 Zeichen in UTF8
    $text3=binarytostring("0x"&stringright($text,20)) ;utf-8

    Du darfst dabei nicht vergessen, dass in UTF-8 "ä", "ö" und "ü" jewils zwei Bytes statt nur einem benötigen.
    Die Zeichen also zeichenweise über die Anzahl der Bytes auszulesen funktioniert in UTF-8 so nicht.

    Im übrigen schreibst du keine Bytes sondern den Hexstring als String in die Datei.
    Das binarytostring($text) macht so ja keinen Sinn, da $text ja nicht vom Typ Binary ist sondern immer noch ein String.
    So klappt alles wie es sollte:

    AutoIt
    $text="0x6D757374657264617465695F5554462D382E7478740D0AC3A4C3B6C3BC270D0A"
    
    
    ;1.Versuch textdatei mit UTF8-Anteil
    filedelete("utf8test.txt")
    filewrite("utf8test.txt", Binary($text))
    
    
    ConsoleWrite(fileread("utf8test.txt"))

    Und so wird noch ein entsprechendes BOM hinzugefügt:

    Und oh! - welch Wunder! Autoit liest tatsächlich korrekt FFFE aus. Ich dachte nur das wundersame Ultra-Edit wäre dazu in der Lage... :D

    6 Mal editiert, zuletzt von AspirinJunkie (18. August 2015 um 16:07)