AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Delphi und Linux - Encoding-Salat?

Ein Thema von knaeuel · begonnen am 8. Aug 2019 · letzter Beitrag vom 9. Aug 2019
Antwort Antwort
Seite 1 von 2  1 2   
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#1

Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 12:33
Ich bastele gerade an einer XML-Schnittstelle, welche unter Linux und Windows funktionieren soll. Die XML-Dateien kommen ISO-8859-1 kodiert hier an. Das sollte "ANSI - Lateinisch I" entsprechen, wenn ich das richtig sehe.

Unter Windows gibt es keinerlei Probleme mit den Dateien. Einfach in den Parser werfen und los gehts. Linux ist da schon etwas zickiger. Sobald eine Datei geladen wird, die einen Umlaut (ä,ö,ü) enthält, kommt die Fehlermeldung

"No mapping for the Unicode character exists in the target multi-byte code page"

Dasselbe würde sicherlich auch noch bei dem einen oder anderen Sonderzeichen passieren.

Ok, kein Problem, dachte ich mir. Konvertieren wir halt die Dateien zu Unicode, dann sollte es laufen. Zur Konvertierung gibt es ein prima Beispiel von Delphi - rausgesucht und in mein Programm eingebaut.

Unter Windows und unter Linux kann ich jetzt das Encoding der XML-Dateien anzeigen lassen und wandeln und wieder anzeigen lassen. Theoretisch... Folgendermaßen sind die Ergebnisse, wenn ich die Kodierung von einigen Dateien mit Windows und mit Linux bestimmen lasse (Spalten "Abfrageergebnisse") und wenn ich versuche, die XML-Datei mit dem Parser zu öffnen:
encoding-tabelle.png

Für mich ist das Encoding-Thema ziemlich neu. Ist es erwartungsgemäß, dass Windows die Ascii-Datei für Ansi erklärt? Und wie siehts mit Linux aus? Liegt das mit den ganzen angeblichen UTF-8-Dateien am Dateisystem? Oder macht mein Code nicht was er soll? Oder hat Ddelphi da Schwächen?

Quellcode: Umwandlung
Delphi-Quellcode:
function TDM_XMLSchnittstelle.ConvertFile(filename:string;destination:TEncoding;filename_option:integer):string;
var LBuffer: TBytes;
    LByteOrderMark: TBytes;
    LOffset: Integer;
    LEncoding, DestEncoding: TEncoding;
    LFileStream: TFileStream;
    out_filename:string;
begin
  LEncoding:= nil;
  DestEncoding := destination;
  LFileStream := TFileStream.Create(filename, fmOpenRead);
  try
    //Datei einlesen und im LBuffer ablegen
    SetLength(LBuffer, LFileStream.Size);
    LFileStream.ReadBuffer(Pointer(LBuffer)^, Length(LBuffer));

    //aktuelle Kodierung einlesen
    LOffset := TEncoding.GetBufferEncoding(LBuffer, LEncoding);
    //Konvertierung zur gewünschten Ziel-Kodierung durchführen
    LBuffer := LEncoding.Convert(LEncoding, DestEncoding, LBuffer, LOffset, Length(LBuffer) - LOffset);
  finally
    LFileStream.Free;
  end;

  if filename_option=0 then
    out_filename:=filename
  else if filename_option=1 then
    out_filename:=filename+'.converted'
  else if filename_option=2 then
    out_filename:=filename+'.'+DestEncoding.EncodingName;

  LFileStream := TFileStream.Create(out_filename, fmCreate);
  try
    //zuerst Encoding-Byte-Order-Mark in die Datei schreiben
    LByteOrderMark := DestEncoding.GetPreamble;
    LFileStream.Write(LByteOrderMark[0], Length(LByteOrderMark));
    //danach den Buffer wegschreiben
    LFileStream.Write(LBuffer[0], Length(LBuffer));
  finally
    LFileStream.Free;
  end;
end;
Quellcode Abfrage der Kodierung:
Delphi-Quellcode:
function TDM_XMLSchnittstelle.GetCurrentEncoding(filename:string):TEncoding;
var LBuffer: TBytes;
    LOffset: Integer;
    LEncoding: TEncoding;
    LFileStream: TFileStream;
begin
  LFileStream := TFileStream.Create(filename, fmOpenRead);
  try
    //Datei einlesen und im LBuffer ablegen
    SetLength(LBuffer, LFileStream.Size);
    LFileStream.ReadBuffer(Pointer(LBuffer)^, Length(LBuffer));
    //aktuelle Kodierung einlesen
    LEncoding:= nil; //<-- wichtig, weil die nächste Procedure sonst Käse zurückliefert!
    LOffset := TEncoding.GetBufferEncoding(LBuffer, LEncoding);
  finally
    LFileStream.Free;
  end;
  result:=LEncoding;
end;
Als Quelldatei diente ursprünglich eine ANSI-Datei, die ich mit dieser Konvertierungs-Function umgewandelt habe (unter Windows).

Warum wird ASCII unter Windows nicht als ASCII erkannt?
Warum erkennt Linux gleich mehrere Kodierungen als UTF-8?
Wolfgang
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#2

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 12:49
Wenn du die XML-Datei hier noch gepostet hättest, dann wäre es etwas einfacher.
(Muss ja nicht das Original sein, sondern eine beispielhafte die das gleiche Verhalten zeigt)
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 13:07
oh ja, kein Problem, in der zip-Datei befinden sich 6 varianten derselben Datei in unterschiedlichen Kodierungen, alle mit Windows mit dem obigen Code umgewandelt. Das Original liegt ebenfalls dabei.

XML Dateien.zip
Wolfgang
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#4

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 13:13
Ja, das ist kein Wunder, denn du schreibst in der XML-Datei
XML-Code:
<?xml version="1.0" encoding="ISO-8859-15"?>
...
was für ein Encoding du verwendest ... aber du hälst dich daran einfach nicht, sondern nimmst jedes Encoding, was dir in den Sinn kommt.

Also, wenn du ein XML-Datei in UTF-16 kodiert speicherst, dann muss die Datei anfangen mit
XML-Code:
<?xml version="1.0" encoding="UTF-16"?>
...
und wenn du die in UTF-8 kodiert speicherst, dann muss die Datei anfangen mit
XML-Code:
<?xml version="1.0" encoding="UTF-8"?>
...
oder
XML-Code:
<?xml version="1.0"?>
...
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 13:38
nein, das trifft das Problem nicht. Selbstverständlich korrigiere ich die erste Zeile bei Bedarf, bevor ich die Daten dem XML-Parser vorwerfe.

Was die Kodierung angeht, sind wir einfach nur bei Textdateien. Die Konvertierungsversuche bzw. das Einlesen der Kodierung ist völlig unabhängig vom XML-Code. Da wird nichts ausgewertet.

Der Fehler "No mapping for the Unicode character exists in the target multi-byte code page" tritt auf, sobald die Datei in eine Stringlist geladen wird. z.B. so:

Delphi-Quellcode:
var dat:TStrings;
...
dat:=TStringlist.Create;
dat.LoadFromFile(dateiname); //<-- erzeugt Fehler unter Linux
Wolfgang

Geändert von knaeuel ( 8. Aug 2019 um 13:40 Uhr)
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
2.905 Beiträge
 
Delphi 2010 Enterprise
 
#6

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 13:46
Die Varianten sind ja wohl im Versuch entstanden, es Linux recht zu machen, wenn ich das richtig verstanden habe.

Aber letztlich ist es wie es ist, einer der Vorteile von XML ist, dass die Datei selbst klar definiert, wie die Kodierung ist. Das muss man dann "einfach" einhalten.
Linux kann das mit Sicherheit. Im eigenen Programm muss man natürlich selber dafür sorgen.

@roter Kasten.
Auch wenn man die Codierung ignoriert, muss ja nichts gutes dabei rauskommen
Gruß, Jo
  Mit Zitat antworten Zitat
knaeuel

Registriert seit: 2. Jul 2007
110 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 13:51
Danke für die Antworten bis hierhin, aber bitte geht doch auf die Fragen ein:

Warum wird ASCII unter Windows nicht als ASCII erkannt?
Warum erkennt Linux gleich mehrere Kodierungen als UTF-8?

Siehe Tabelle:
encoding-tabelle-klein.png

Vergesst dabei bitte den XML-Part und stellt euch vor, es ginge einfach nur um Textdateien.
Wolfgang

Geändert von knaeuel ( 8. Aug 2019 um 13:53 Uhr)
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.541 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 13:58
XML Reader bekommen die encoding Info aus dem XML Header.
Gewöhnliche Textdateien haben ein Byte-Order-Mark (BOM)

Warum wird die xml Datei in eine StringList eingelesen?

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
2.905 Beiträge
 
Delphi 2010 Enterprise
 
#9

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 14:03
Um die Fragen zu beantworten, müsste man die Implementierung von getbufferencoding kennen und sie mit Deinen Textdateibeispielen debuggen?
Ist diese Frage, also eigentlich "getBufferEndcoding" überhaupt deterministisch? Oder ist es eine Frage davon, welches Stück Text gerade im Buffer steckt?
Wenn mehrere Encodings als Antwort möglich sind, welche gibt getBufferEncoding zurück?
Kann der Text auch kaputt encoded sein oder schließt Du das aus?
Gruß, Jo
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#10

AW: Delphi und Linux - Encoding-Salat?

  Alt 8. Aug 2019, 15:03
Delphi-Referenz durchsuchenTEncoding.GetBufferEncoding

Und die Doku sagt, nur wenn es ein BOM gibt, dann gibt es ein passendes Encoding zurück, ansonsten gibt es Default zurück.

Und bei ASCII gibt es kein BOM also ...
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

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 01:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf