AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Vorstellung Unit: File encoding detector

Vorstellung Unit: File encoding detector

Ein Thema von LTE5 · begonnen am 19. Nov 2017 · letzter Beitrag vom 15. Jan 2018
Antwort Antwort
Seite 1 von 4  1 23     Letzte » 
LTE5
Registriert seit: 13. Nov 2017
Ich möchte euch gerne meine Arbeit aus den vergangenen Tagen vorstellen.
Ich bin kein Profi und habe mich erst vor wenigen Tagen in Streams eingelesen.

Ich brauchte eine Lösung, um mehr oder weniger zuverlässig das Encoding einer Datei herausfinden zu können.
Über BOM ist das ja leider nicht immer feststellbar, daher habe ich eine andere Lösung entworfen.

Sie ist weder professionell noch gut, aber sie funktioniert. Es ist mehr oder weniger eine Zusammenstellung aus Dingen die ich im Internet gefunden habe.
Daher bitte ich um Feedback! Ihr könnt die Unit auch gerne kopieren, anpassen und hier im Beitrag wieder posten.

Der Aufruf ist einfach
Delphi-Quellcode:
var IsUnicode: Boolean;
begin
 IsUnicode := TEncodingDetect.IsFileUnicode('pfad-zur-datei.txt');
So ist es auch möglich
Delphi-Quellcode:
 Memo1.Lines.Clear;

 Memo1.Lines.Add('File unicode: ' + BoolToStr(TEncodingDetect.IsFileUnicode('pfad-zur-datei.txt'), True));
 Memo1.Lines.Add('String unicode: ' + BoolToStr(TEncodingDetect.IsTextUnicode('ʥ'), True));
 Memo1.Lines.Add('String unicode: ' + BoolToStr(TEncodingDetect.IsTextUnicode('ABC'), True));
 Memo1.Lines.Add('File content: ' + TFile.ReadAllText('pfad-zur-datei.txt', TEncodingDetect.GetEncoding('pfad-zur-datei.txt')));

Geändert von LTE5 (24. Nov 2017 um 14:32 Uhr)
 
Der schöne Günther

 
Delphi 10 Seattle Enterprise
 
#2
  Alt 19. Nov 2017, 14:26
Hallo-

Wenn du statt (oder zumindest zusätzlich zu) String-Pfadangaben den Benutzer auch TStream reinstecken lässt, lassen sich viel besser Unit-Tests dafür schreiben
Es wäre beispielsweise viel einfacher Daten aus einem ZIP-Archiv, einem Email-Anhang oder einem Netzwerk-Stream zu analysieren. So müsste ich ihn erst einmal auf der Platte speichern oder in einen zusätzlichen String speichern.

Als Kritik hätte ich sonst noch die Enumeration TUnicodeType - Mir wäre lieber ich bekäme eine frisch erstellte TEncoding -Instanz zurück. Wahrscheinlich Geschmackssache.

PS: Den Typ "NoBOM" zurückzubekommen wenn die angegeben Datei nicht existiert finde ich ehrlich gesagt nicht gut. Da gehört eine Exception geworfen.
  Mit Zitat antworten Zitat
LTE5

 
Delphi 10.2 Tokyo Starter
 
#3
  Alt 19. Nov 2017, 14:28
Danke erst einmal.
TEncoding wäre mir auch lieber. Was TEncoding aber nicht kennt sind die UTF32-Varianten von Endian. Oder zählt UTF32 unter TEncoding.Unicode?

Was mich auch stört ist, dass ich bei nur einem Aufruf von IsFileUnicode 2x TBytesStream erzeuge, wenn es ganz durch geht.
Das könnte man mit einem Konstruktor und Destruktor-Konstrukt lösen. Aber dann wäre es kein Einzeiler mehr.

Was mir auch nicht gefällt ist die Art und Weise des Vergleichs auf das BOM. Besser bekomme ich es leider nicht hin.

Geändert von LTE5 (19. Nov 2017 um 14:39 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

 
Delphi 10 Seattle Enterprise
 
#4
  Alt 19. Nov 2017, 14:39
Meinst du den Vergleich mit den hardkodierten Werten? Ich würde stattdessen TEncoding.UTF8.GetPreamble() nehmen?

Ich habe so etwas ähnliches in eine Nummer kleiner auch irgendwo herumliegen, aber nur auf der Arbeit. Da kann ich ab nächster Woche ja mal schauen zum Vergleichen...
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

 
Delphi 2006 Professional
 
#5
  Alt 19. Nov 2017, 14:39
Ich habe noch zwei interessante Links dazu:
https://blogs.msdn.microsoft.com/old...7-00/?p=27223/
https://blogs.msdn.microsoft.com/old...24-00/?p=40093
Michael
  Mit Zitat antworten Zitat
Der schöne Günther

 
Delphi 10 Seattle Enterprise
 
#6
  Alt 19. Nov 2017, 14:40
https://en.wikipedia.org/wiki/Bush_hid_the_facts
  Mit Zitat antworten Zitat
LTE5

 
Delphi 10.2 Tokyo Starter
 
#7
  Alt 19. Nov 2017, 14:44
Also im Prinzip habe ich mich Tage lang umsonst bemüht?

Zitat:
Meinst du den Vergleich mit den hardkodierten Werten? Ich würde stattdessen TEncoding.UTF8.GetPreamble() nehmen?
GetPreamble ist gut. Aber TEncoding kennt wie gesagt UTF32 nicht.
Wäre also eine Lösung für alles, bis auf UTF32. Ich füge es oben gleich mal an.

Geändert von LTE5 (19. Nov 2017 um 14:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

 
Delphi 10.3 Rio
 
#8
  Alt 19. Nov 2017, 14:53
Zitat:
Findet sich ein Charakter > 127 (also außerhalb des ASCII-Bereichs), wird unterbrochen denn es ist vermutlich Unicode.
Erfahrungsgemäß ist das gerade im deutschsprachigen Umfeld eher selten der Fall: Ein Zeichen > #127 ist dort in der Regel ein Umlaut.

Nur so als Hinweis: Die Unit System.Character enthält ein paar Methoden für UTF-32 Zeichen und in System ist auch ein Typ UCS4String definiert, der allerdings nichts mit einem üblichen Delphi-String gemein hat.
Uwe Raabe
  Mit Zitat antworten Zitat
LTE5

 
Delphi 10.2 Tokyo Starter
 
#9
  Alt 19. Nov 2017, 15:03
Irgendwie habe ich den Eindruck meine Unit ist mehr als nutzlos in diesem Encoding-Labyrinth.
Aber mehr als "erraten" kann man ja eh nicht. Also versuche ich jedenfalls das.

Wenn jemand eine bessere Unit bauen kann, würde sich jemand dazu bereit erklären?


Zitat:
Findet sich ein Charakter > 127 (also außerhalb des ASCII-Bereichs), wird unterbrochen denn es ist vermutlich Unicode.
Was ich damit meine ist, wenn ein Zeichen > 127 vorkommt, ist es etwas anderes als ANSI.

# Ich habe die Unit in #1 nochmal angepasst.

# Ich habe die Unit in #1 noch einmal angepasst. Rückgabewert ist jetzt TEncoding.
Ich habe lange getestet. Wenn ich nicht gerade in den Kopfdaten einer Datei rumwühle und komische Werte eintrage, wird die Datei immer korrekt gelesen.

# Einen Fall habe ich doch gefunden. Wenn man eine utf-8-Datei ohne BOM prüft und kein Default-Encoding angibt, kommt natürlich ANSI zurück und é kann nicht dargestellt werden.
Deswegen gibt es nun eine überladene Version von TEncodingDetect.GetFileEncoding().

Geändert von LTE5 (19. Nov 2017 um 16:37 Uhr)
  Mit Zitat antworten Zitat
HolgerX

 
Delphi 6 Professional
 
#10
  Alt 19. Nov 2017, 16:47
Hmm..

Zitat:
Findet sich ein Charakter > 127 (also außerhalb des ASCII-Bereichs), wird unterbrochen denn es ist vermutlich Unicode.
Was ich damit meine ist, wenn ein Zeichen > 127 vorkommt, ist es etwas anderes als ANSI.
Nicht ganz:

ASCII entspricht 7 Bit = 0-127
ANSI entspricht 8 Bit = 0-255

https://de.wikipedia.org/wiki/ANSI-Zeichencode

Somit kann ein gültiges ANSI-Zeichen auch als Zahl 240 sein..
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf