Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Einlesen von KAPUTTER Unicode-Datei (https://www.delphipraxis.net/199602-einlesen-von-kaputter-unicode-datei.html)

Codehunter 5. Feb 2019 11:00

Einlesen von KAPUTTER Unicode-Datei
 
Hallo!

Bein Einlesen einer Datei erhalte ich die Exception "Keine Zuordnung für Unicodezeichen in der Multibyte-Zielcodeseite vorhanden". Beim Durchschauen habe ich festgestellt, es sind in der Datei tatsächlich ALLE Sonderzeichen geschrottet und durch die Zeichenfolge
Code:
�
(aus ANSI-Sichtweise, alle gleich, egal was es vorher mal war) ersetzt worden. Das ist serverseitig passiert und außerhalb meines Einflussbereiches. Das ist zwar doof, sollte aber nicht dazu führen dass mein Programm beim Einlesen aufgibt. Vielmehr hätte ich gerne, dass nicht dekodierbare Unicode-Zeichen als "?" ausgegeben werden. Kann man das mit wenig Aufwand hier ergänzen oder muss ich die gesamte Datei "zu Fuß" scannen?
Delphi-Quellcode:
  LReader := TStreamReader.Create(AStream, TEncoding.Unicode, True, 2048);
  try
    FZeileNr := 0;
    while LReader.Peek >= 0 do begin
      ZeileVerarbeiten(LReader.ReadLine);
      Inc(FZeileNr);
    end;
  finally
    FreeAndNil(LReader);
  end;
Das ist auch insofern sehr wichtig, damit nicht dekodierbare Zeichen nicht dazu führen, dass sich Multibyte-Zeichen zu mehreren Singlebyte-Zeichen "vermehren" weil das die Logik durcheinander bringt.
Grüße
Cody

Redeemer 5. Feb 2019 11:29

AW: Einlesen von KAPUTTER Unicode-Datei
 
Du liest ja die Datei als UTF-16LE ein. � ist aber UTF-8. Ist das gewollt?

Codehunter 5. Feb 2019 11:48

AW: Einlesen von KAPUTTER Unicode-Datei
 
Wie gesagt, die Datei ist kaputt. Sie hat eine Unicode-Preamble, aber die Sonderzeichen sind vermurkst. Gut möglich, dass das ein Mischmasch aus Unicode und UTF8 ist. Mir geht es aber nur um eine Art Failsafe-Modus. So dass der Anwender 90% lesen kann. Immer noch besser als eine schnöde Fehlermeldung und Ende Gelände.

freejay 5. Feb 2019 12:44

AW: Einlesen von KAPUTTER Unicode-Datei
 
Du könntest die Datei im Falle des Fehlers nochmals einlesen mit TEncoding.UTF8 als Vorgabe?

Nee, sorry, das war Quatsch, das geht bei einer ANSI-Datei, aber nicht bei fixer Mehr-Byte-Codierung (UNICODE)...

Uwe Raabe 5. Feb 2019 12:48

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von freejay (Beitrag 1424748)
Du könntest die Datei im Falle des Fehlers nochmals einlesen mit TEncoding.UTF8 als Vorgabe?

Was überhaupt nichts bringt, wenn die Datei
Zitat:

ein Mischmasch aus Unicode und UTF-8 ist
.

freejay 5. Feb 2019 12:52

AW: Einlesen von KAPUTTER Unicode-Datei
 
Ja, ist mir auch schon aufgefallen... (s.o.) *schäm*

freejay 5. Feb 2019 12:53

AW: Einlesen von KAPUTTER Unicode-Datei
 
Ich arbeite halt immer nur mit ANSI oder UTF8...

Codehunter 5. Feb 2019 12:56

AW: Einlesen von KAPUTTER Unicode-Datei
 
Jepp, so seh ich das auch. Wenn ich die Datei mit Notepad++ öffne, dann werden eben jene defekten Zeichen als ein Platzhalter-Rechteck angezeigt. Genau so würde ich das auch gern machen. Irgendein Platzhalter, der wenigstens die Zeichenlänge reserviert, sodass nachfolgende nicht nach rechts weiter gerückt werden.

freejay 5. Feb 2019 13:25

AW: Einlesen von KAPUTTER Unicode-Datei
 
In meinem Umfeld und bei meinen Anwendungen kann ich mir nicht vorstellen, dass es Sinn macht, mit dieser kaputten Datei weiterzuarbeiten.

Wenn es sich hier also um einen Einzelfall handelt: Warum sollte das Programm dann nicht mit einem - sauber abgefangenen :-) - Fehler aussteigen?

Wenn das öfter vorkommt, müsste man wahrscheinlich doch den langen Weg beschreiten und die Ursache des Fehlers angehen.

hoika 5. Feb 2019 14:32

AW: Einlesen von KAPUTTER Unicode-Datei
 
Hallo,
hm, so viele verschiedene (deutsche) Sonderzeichen gibt es doch eigentlich gar nicht.
Kannst du die kaputten Zeichen nicht einfach ersetzen?

StringList.LoadFromFile
StringReplace StringList.Text


Das macht natürlich nur Sinn, wenn die häufiger solche Dateien bekommst.

Redeemer 5. Feb 2019 14:36

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von Codehunter (Beitrag 1424753)
Jepp, so seh ich das auch. Wenn ich die Datei mit Notepad++ öffne, dann werden eben jene defekten Zeichen als ein Platzhalter-Rechteck angezeigt.

Das kann aber nicht sein. Bei UTF-16 besteht jedes Zeichen aus 2 oder 4 Bytes, deine ANSI-Fehlersequenz (sie bedeutet das Platzhalterzeichen �) hat aber 3 Bytes, sprich der Editor würde danach falsche Bytes zu einem Zeichen zusammenfassen.

freimatz 5. Feb 2019 14:52

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von hoika (Beitrag 1424756)
hm, so viele verschiedene (deutsche) Sonderzeichen gibt es doch eigentlich gar nicht.

Es geht sicher nicht nur um deutsche Sonderzeichen. Da gibt es tausende. :wink:

Uwe Raabe 5. Feb 2019 14:53

AW: Einlesen von KAPUTTER Unicode-Datei
 
Ich bin mir gar nicht mehr sicher, ob es sich wirklich um eine UTF-16 codierte Datei handelt. Im TStreamReader.Create wird zwar ein TEncoding.Unicode übergeben, aber für das DetectBOM wiederum ein True. Damit wird das Unicode-Encoding lediglich zum Fallback, wenn kein BOM gefunden wird.

stifflersmom 5. Feb 2019 14:54

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von hoika (Beitrag 1424756)
Kannst du die kaputten Zeichen nicht einfach ersetzen?

Wenn alle falschen Zeichen mit der zeichenfolge
Zitat:

�
ersetzt wurden, macht das nicht viel Sinn.

hoika 5. Feb 2019 14:57

AW: Einlesen von KAPUTTER Unicode-Datei
 
Hallo,
Zitat:

Bein Einlesen einer Datei erhalte ich die Exception
Es steht nicht, einer beliebigen Datei ...

Codehunter 5. Feb 2019 15:12

AW: Einlesen von KAPUTTER Unicode-Datei
 
Das Problem ist, ich weiß ja nicht welche Zeichen kaputt sind. Bei dieser Datei schon, aber es könnte auch eine beliebig andere kaputte Datei geladen werden. Dort liegen wieder andere Kodierfehler vor. Also einfach Suchen und Ersetzen ist nicht.

Aber wenn ich so in die Quellen von TEncoding schaue dann wird für solche Zeichen tatsächlich nichts anderes gemacht als ein RAISE und fertig. Um das zu ändern müsste ich wohl ein komplett eigenes TEncoding schreiben, weil die Methode TEncoding.GetString (wo das RAISE passiert) nicht virtuell ist. Ich glaub da stehen Aufwand und Nutzen in keinem Verhältnis.

EDIT:
Zitat:

Zitat von Uwe Raabe (Beitrag 1424759)
Ich bin mir gar nicht mehr sicher, ob es sich wirklich um eine UTF-16 codierte Datei handelt. Im TStreamReader.Create wird zwar ein TEncoding.Unicode übergeben, aber für das DetectBOM wiederum ein True. Damit wird das Unicode-Encoding lediglich zum Fallback, wenn kein BOM gefunden wird.

Genau so ist das auch beabsichtigt. Ich wollte damit erreichen, dass die Preamble (BOM ist ja eigentlich nur ein Teil dessen) ausgewertet wird. Erst wenn das komplett vor die Wand geht, gebe ich Unicode fest vor. Bei der besagten Datei kann aber auch Notepad++ die kaputten Zeichen nicht retten, egal wie man an der Kodierung dreht. Insofern betrachte ich die Preamble als korrekt und den Inhalt als defekt. Die Datei kommt mit einer Unicode-Preamble. Aber auch anders herum, wenn ich hardcoded UTF8 als Reader-Encoding vorgebe und die Preamble ignoriere, laufe ich in genau die selbe Exception.

Uwe Raabe 5. Feb 2019 15:27

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von Codehunter (Beitrag 1424762)
Die Datei kommt mit einer Unicode-Preamble.

Dann dürfte das GetString aber eigentlich nicht krachen, denn GetCharCount liefert bei TUnicodeEncoding lediglich
Delphi-Quellcode:
ByteCount div SizeOf(Char)
und GetChars macht ein simples Move.

Was sagt denn der Debugger dazu?

Redeemer 5. Feb 2019 17:37

AW: Einlesen von KAPUTTER Unicode-Datei
 
Dieser Thread hat keinen Sinn mehr ohne dass du hier einen Screenshot aus einem Hex-Editor (HxD z.B., guck mal auf delphipraxis.net) postest. Da reichen auch die ersten zehn Bytes. Damit ist der Thread sofort, eindeutig und vollumfassend erledigt. Ich bin mir, wie ich bereits im ersten Post geschrieben habe, ziemlich sicher, dass das Problem vor dem PC sitzt und nicht weiß, was für ein Encoding die Datei hat. Eine Datei kann wie erwähnt technisch gesehen unmöglich gleichzeitig eine dreiteilige ANSI-Sequenz und UTF-16-Codepoints enthalten, ohne dass ziemlich genau die Hälfte der Datei aus überwiegend CJK-Zeichen bestände.

Zitat:

Zitat von Codehunter (Beitrag 1424728)
tatsächlich ALLE Sonderzeichen geschrottet

Wenn keine Sonderzeichen außer der UTF-8-Sequenz drin sind, sehe ich kein Problem damit, diese eine Sequenz einmalig zu ersetzen.

freimatz 6. Feb 2019 06:55

AW: Einlesen von KAPUTTER Unicode-Datei
 
Was meinst du mit "dreiteilige ANSI-Sequenz"? Und was meint ihr mit "Sonderzeichen"? Der Begriff kommt wenn ich danach Google bei Unicode nicht vor. Auch bei den Kategorien nicht (https://www.compart.com/de/unicode/category).

p80286 6. Feb 2019 08:23

AW: Einlesen von KAPUTTER Unicode-Datei
 
Ich würde es etwas anders formulieren, aber Redeemer hat recht. Ohne einen Hexdump ist das alles nur Spökenkiekerei. Jede Datei enthält binäre Daten. Wenn Ihre Anzeige einen sinnvollen Text ergibt, dann stimmt die Interpretation (zufällig?).

Gruß
K-H

Codehunter 6. Feb 2019 08:39

AW: Einlesen von KAPUTTER Unicode-Datei
 
Ich beende das Thema hier mal, weil wir von der eigentlichen Frage immer weiter abkommen. Es ging darum, ob man den Streamreader dazu bekommt, nicht erkannte Zeichen, für die es keinen Eintrag in der Codetabelle gibt, durch ein Platzhalterzeichen zu ersetzen. Die RTL kann das in der jetzigen Form nicht wie ich inzwischen festgestellt habe. Daher bleibt wohl oder übel nur eine Fehlermeldung auszugeben.

@Redeemer: Bevor du irgendwen angreifst solltest du vielleicht erst mal den ganzen Thread lesen. Danke.

Redeemer 6. Feb 2019 09:03

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von freimatz (Beitrag 1424783)
Was meinst du mit "dreiteilige ANSI-Sequenz"?

Steht im Eröffnungspost.
Zitat:

Zitat von freimatz (Beitrag 1424783)
Und was meint ihr mit "Sonderzeichen"?

Das Gegenteil von ASCII.

Codehunter 6. Feb 2019 09:48

AW: Einlesen von KAPUTTER Unicode-Datei
 
Zitat:

Zitat von Redeemer (Beitrag 1424806)
Zitat:

Zitat von freimatz (Beitrag 1424783)
Was meinst du mit "dreiteilige ANSI-Sequenz"?

Steht im Eröffnungspost.

Nicht meine Wortwahl.
Zitat:

Zitat von Redeemer (Beitrag 1424806)
Zitat:

Zitat von freimatz (Beitrag 1424783)
Und was meint ihr mit "Sonderzeichen"?

Das Gegenteil von ASCII.

Falsch. Eigentlich alles > ANSI (127)


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:38 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz