Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?



  • Guten Tag

    Da in meiner etwas betagten Visual Studio Version keine Unicode Unterstützung für Textdateien vorhanden ist, habe ich mir eine Klasse von CFile abgeleitet mit der ich Unicode und Ansi Dateien ohne Probleme einlesen kann.

    Jetzt habe ich das Problem das die Unsitte Unicodedateien ohne BOM abzuspeichern immer weiter um sich greift.

    UTF 16 und 32 kann ich ja noch einigermaßen sicher auch ohne BOM erkennen.
    Aber wie zum Henker mache ich das bei UTF8?

    Eine Möglichkeit währe eine Datei komplet zu laden und dann zu schaun ob ß, ä, ö, ü,... darin vorkommen.
    Aber wie kann ich da sicher sein dass die Datei dann UTF8 ist und nicht ein englisch geschriebener Text?
    Außerdem ist das ja auch nicht wirklich performant.

    Kann mir bitte jemand auf die Sprünge helfen?
    Denn wie es aussieht schafft es ja selbst der Windows Notepad und Google bringt auch oft nur "Wenn kein BOM vorhanden ist, einfach raten".

    Ich bin schon langsam am Verzweifeln.



  • @siegfried_zynzec sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    Aber wie kann ich da sicher sein dass die Datei dann UTF8 ist und nicht ein englisch geschriebener Text?

    Da es keinen Unterschied gibt, ist es sowohl UTF8 als auch ASCII.


  • Mod

    Etwas, das du gucken kannst, ist, ob die Datei gültiges UTF8 ist. Jede gültige UTF8-Datei ist auch automatisch eine gültige ANSI-Datei, aber nicht umgekehrt.

    Das hat natürlich eine gewisse Fehlerrate, da gepaarte ANSI-Sonderzeichen wie ein UTF8-Sonderzeichen ausschauen. Das ist dann halt nicht mehr unterscheidbar, außer man versucht wirklich, den Sinn des Textes zu verstehen, welches Zeichen an der Stelle nun passend wäre. Was sicherlich ein ganz interessantes Projekt für eine Bachelorarbeit wäre, aber vielleicht doch etwas den Rahmen sprengt 🙂

    Die Wahrscheinlichkeit, dass eine ANSI-Datei nur mit zufällig gültigen UTF8-Sequenzen kommt ist, ist aber recht gering bei "natürlichen" Texten. Da müsste dir schon wirklich jemand absichtlich einen reinwürgen wollen.

    @manni66 sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    @siegfried_zynzec sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    Aber wie kann ich da sicher sein dass die Datei dann UTF8 ist und nicht ein englisch geschriebener Text?

    Da es keinen Unterschied gibt, ist es sowohl UTF8 als auch ASCII.

    Er hat aber ANSI gefragt, nicht ASCII. ANSI ist diese 8-Bit Erweiterung von ASCII mit den dummen Codepages. Die noch einmal ein ganz eigenes Kapitel an Problemen sind, denn man muss schließlich wissen, welche Codepage ein ANSI-Text ist, um ihn korrekt interpretieren zu können. Was man so einem Text normalerweise auch nicht ansehen kann. Daher: UTF8 everywhere!



  • @seppj

    Er hat aber ANSI gefragt, nicht ASCII. ANSI ist diese 8-Bit Erweiterung von ASCII mit den dummen Codepages

    Englischer Text (nach dem er gefragt hat) ist 7 Bit ASCII, ISO-8859-15, UTF8, Latin 1 und was mir alles nicht einfällt. Da gibt’s leider (oder auch zum Glück) nichts zu Unterscheiden.



  • Die oberen Bits dürfen bei UTF-8 auch nicht beliebig sein.

    Beim ersten Byte eines Multichars sind die beiden höchsten Bits immer 11, danach 10.

    An der Anzahl der 1en kann man auch erkennen, wieviel Folgebytes kommen.

    Wenn diese Regel verletzt wird, ist es kein UTF-8.



  • @siegfried_zynzec sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    "Wenn kein BOM vorhanden ist, einfach raten"

    Ja, genau. Ist auch die einzige Möglichkeit. Man kann Code schreiben der relativ schlau im Raten ist, aber im Endeffekt bleibt es geraten und kann falsch geraten sein.

    Ich bin schon langsam am Verzweifeln.

    Was willst du eigentlich genau erreichen? Also was ist der Anwendungsfall - wo und wann wird wie und warum was für ein File ausgelesen in dem was für Text steht?



  • Danke für eure Hilfe.

    Ich habe jetzt eine Funktion geschrieben, die die Dateien nach Unicodezeichen durchsucht.
    Das funktioniert zwar, ist aber langsamer als zuvor.

    Zur Erklährung

    Wo:
    In der Arbeit einer kleinen Kammer auf einem Win7 PC der als Fileserver für CNC Maschinen und zur Fehler & Reportauswertung verwendet wird.

    Wann:
    Alle 6 Stunden bzw. auf Anfrage über Intranet.

    Wie:
    Die Auswertung und Weitergabe der Daten erfolgt mit einem innerhalb der Firma erstellten Programm bei dem ich die Aufgabe habe es zu pflegen.

    Alle möglichen Steuerungen, Leitrechner usw. spielen in unregelmäßigen Abständen Reports mit Status + Fehlermeldungen als Textdatei in einen zentralen Ordner.
    Die generierenden Systeme sind von Betriebssystemlose Bar-Metal Lösungen in Steuerungen über alle verfügbaren Dos & Windows-Versionen.
    Die Übergabe der Daten erfolgt mittels RS232, Ethernet, Can Bus, LWL, GPIO, Profibus und Centronix Parallelport.
    (Bei zwei Maschinen bestünde noch die Möglichkeit die Daten mittels Lochstreifen bzw. Diskette zu übergeben, aber das tut sich keiner mehr an.)

    Warum:
    Es werden alle Fehlermeldungen, Statuswerte und Prozessparameter zurückgegeben um rechtzeitig zu erkennen wenn einzelne Maschinen Probleme haben. (Wartung, zusätzliches Material zur Verfügung stellen, Ersatzteilbestellung / -fertigung,....

    Damals wurde festgelegt das alle Dateien mit Datum + Uhrzeit abgelegt zu werden haben.
    Leider gibt es keine Möglichkeit die Maschinen anhand des Dateinamens zu erkennen.

    Die neuen Maschinen bzw. Rechner liefern alle die Daten als UTF16 mit und ohne BOM.
    Leider liefert die neueste Maschine eben UTF 8 ohne BOM. (Dies liese sich leider nur mit einer obszönen Menge an Geld ändern.)

    Und das bringt den alten (nicht von mir geschriebenen) Parser zum Abschmieren.

    Da ich aktuell keine Zeit hatte alles neu zu schreiben hatte ich nach einer schnellen & einfachen Methode gesucht dies zu kompensieren.
    Ich bin jetzt der Dritte, der sich vornimmt, sobald er Zeit hat das Ganze neu zu schreiben da es eigentlich nur eine Flickschusterrei ist.
    (Ich fürchte mit der Umstellung auf Win10 wird es mich spätestens 2020 erwischen.)


  • Mod

    Das impliziert jetzt aber eine ganz andere Frage, als du gestellt hast. UTF16 ist trivial von ASCII, ANSI, und UTF8 zu unterscheiden.



  • Der BOM bei UTF-8 ist auch optional. Nur für UTF-16/32 ist er zwingend notwendig. Damit ein parser auch das byte ordering erkennen kann (little vs big endian)

    Die Frage ist was stellt das programm mit den Daten an?



  • @siegfried_zynzec Und die Maschinen müssen unbedingt alle direkt in das selbe Verzeichnis reinschreiben, und es müssen auch unbedingt die unbrauchbaren Namen weiterverwendet werden?



  • @seppj
    Mit UTF16 hatte ich ja auch keine Probleme.
    Nur UTF8 hatte mir Kopfschmerzen bereitet.

    Und das habe ich jetzt behoben indem ich die Dateien nach UTF8 Kennzeichen gesucht wird bevor die Daten weiterverarbeitet werden.

    @firefly
    Die Daten werden aus den Dateien ausgelesen und dann in eine große CSV Datei geschrieben und in eine SQL Datenbank geschrieben.
    Auf diese Daten greifen dann die verschiedensten Abteilungen zu.
    Die Instandhaltung ermittelt daraus den allgemeinen "Gesundheitszustand" der Maschinen.
    Die Arbeitsvorbereitung erfährt den Produktionsstatus der einzelnen Teile
    Die Vorrichtungskonstruktion erfährt wann welche Teile gefertig werden um ihre Arbeit darauf abzustimmen
    Und die verschiedesten Analysetools werden auch noch damit versorgt um schöne bunte Diagramme zu erstellen.

    Kurz gesagt, die Datenkrake wird gefüttert.

    @hustbaer
    Leider muss das so sein, da das vor Jahrzehnten von EDV Spezialisten entworfen wurde.
    Das konnten meine Vorgänger nicht ändern und ich leider auch nicht.
    Ich bin nur der "Nebenbeiprogrammierer".
    Ich habe die EDV-Infrastruktur nicht zu hinterfragen da sie wichtigen (teuren) Personen entworfen wurde und somit perfekt ist.



  • @siegfried_zynzec sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    Leider gibt es keine Möglichkeit die Maschinen anhand des Dateinamens zu erkennen.

    Geht das über den Ersteller/Eigentümer der Datei?
    (oder schreiben alle Geräte unter derselben UserId auf den Server?)

    @siegfried_zynzec sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    Ich habe jetzt eine Funktion geschrieben, die die Dateien nach Unicodezeichen durchsucht.
    Das funktioniert zwar, ist aber langsamer als zuvor.

    Beim ersten Auftreten eines Nicht-Unicodezeichens kannst du aufhören, dann ist es kein Unicode.



  • Geht das über den Ersteller/Eigentümer der Datei?
    (oder schreiben alle Geräte unter derselben UserId auf den Server?)

    Leider ist der Eigentümer der Dateien entweder Administrator oder der PC auf dem das Programm läuft.
    Und die Zuteilung dieser Eigentümer erfolgt ohne ersichtlichem Muster.

    @dirkb sagte in Wie unterscheide ich zwischen Ansi und UTF8 ohne BOM?:

    Beim ersten Auftreten eines Nicht-Unicodezeichens kannst du aufhören, dann ist es kein Unicode.

    Danke für den Hinweis.

    Vielen Dank für eure Hilfe.
    Ich habe das Ganze dank eurer Hilfe wieder zum Laufen bekommen.


Anmelden zum Antworten