Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Textdatei utf8-kodiert speichern! (https://www.delphipraxis.net/76573-textdatei-utf8-kodiert-speichern.html)

SirRobert 6. Sep 2006 12:12


Textdatei utf8-kodiert speichern!
 
Hallo zusammen,

ich habe eine Frage:
wie kann ich erzwingen (unabhängig vom Inhalt), dass ein String in eine UTF-8
codierte Textdatei gespeichert wird. Ich habe bereits mit Utf8Encode(mystr),
dann write(f, mystr) versucht, doch die Textdatei wird immer als ANSI gespeichert.

Für Eure Hilfe bedanke ich mich im voraus!


Grüße

Robert

Bernhard Geyer 6. Sep 2006 12:18

Re: Textdatei utf8-kodiert speichern!
 
Wie siehst du das es nur ANSI wäre?
Doch etwa nicht mit Notepad?
Für Notepad benötigst du nocht den Byte Order Mark für eine UTF8-Codierte Datei.

SirRobert 6. Sep 2006 12:26

Re: Textdatei utf8-kodiert speichern!
 
Hallo Bernhard,


doch, im Notepad! :)
Und diesen Byte Order Mark für eine UTF8-Codierte Datei bekomme ich
wie hin?

Übrigens, Danke für die schnelle Antwort!


Robert

SirRobert 6. Sep 2006 12:49

Re: Textdatei utf8-kodiert speichern!
 
Hat sich erledigt!

Schöne Grüße


Robert

Sherlock 10. Apr 2012 09:50

AW: Textdatei utf8-kodiert speichern!
 
Verdammt! Und genau hier hätte ich gerne gewusst, wie sich das erledigt hat. :evil:

Ich stehe vor einem sehr ähnlichen Problem. Ich bin im D2007 und hantiere mit UTF8Strings, die speicher ich dann irgendwann in ein TextFile (evtl. hier schon der Fehler?). Alles sieht im Editor nett aus, ein third-party-tool meckert auch erstmal nicht über das Format. Sobald Umlaute ins Spiel kommen, ist aber der Ofen aus. Das Tool jammert über "Ungueltiges Byte 2 von 3-Byte-UTF-8-Sequenz." und im NotePad++ (der übrigens annimmt, das wäre "UTF8 ohne BOM", stehen statt Umlauten Sonderzeichen...:pale:

Kurz gesagt: Hülfe?

Sherlock

himitsu 10. Apr 2012 10:01

AW: Textdatei utf8-kodiert speichern!
 
Du Schreibst das UTF-8-BOM in die Datei und hinten drann deinen als UTF-8 kodierten Text.

Ab D2009 sollte man besser den UTF8String oder den RawByteString verwenden, anstatt dem AnsiString.

Du mußt aber aufpassen, denn die alten Pascal-Prozeduren ala WriteLn arbeiten ausschließlich mit ANSI (auch in den neueren Unicode-Delphis) ... UTF8 kann zwar als ANSI behandelt werden, aber man sollte aufpassen, daß es nicht irgendwo zu einer automatischen Konvertierung kommt, bei einer Zuweisung von UTF8 an ANSI.


Ab D2009 hätte ich eine TStringList vorgeschlagen, welcher man das Encoding mitgeben kann.

Falls alles nichts hilft, schreib den UTF8String, inkl. BOM, in einen FileStream.

Sherlock 10. Apr 2012 10:05

AW: Textdatei utf8-kodiert speichern!
 
OK, das hatte ich befürchtet. TextFile und WriteLn geht nicht mit UTF8. Dann schau ich, daß ich das in einen hübschen Stream packe.

Danke, Himitsu.

Sherlock

himitsu 10. Apr 2012 10:18

AW: Textdatei utf8-kodiert speichern!
 
Es geht schon mit UTF8.

Man muß eben nur etwas aufpassen.

Sherlock 10. Apr 2012 10:53

AW: Textdatei utf8-kodiert speichern!
 
Klar geht es, das hab ich ja gesehen, nur bei Umlauten wirds halt kriminell. Und da kann ich nicht wirklich aufpassen, bzw. das einzige wäre Umlaute umzuwandeln in ihr zweibuchstabiges Pendant. Oder was meinst Du?

Mit dem Stream stosse ich übrigens auf andere Geschichten. Ich gebe zu, ich habe bisher Texte nur als TextFiles gespeichert und TFileStream nie verwendet.

Mein Versuch:
Delphi-Quellcode:
var ExportText : UTF8String;
    myfStream : TFileStream;
.
.
.
      fExpFileName := fDateiPfad + GUIDohneKlammern + '.xml';
      myfStream := TFileStream.Create(fExpFileName, fmCreate);

      ExportText := #239 + #187 + #191 + ExportText;  // Ist das ausreichend als BOM?

      myfStream.Write(ExportText,Length(ExportText));
Führt zu einer unleserlichen Datei. Muss ich mit dem BOM noch was anderes anstellen? Ist das die Falsche Art den BOM einzufügen?

Sherlock

himitsu 10. Apr 2012 11:10

AW: Textdatei utf8-kodiert speichern!
 
Delphi-Quellcode:
// besser als explizite Unicodeangabe, also 4-stellig, damit keine Codepage in die Quere kommen kann
ExportText := #$00EF#$00BB#$00BF + ExportText;

// oder gleich das korrekte Zeichen (das #$FEFF ist der Unicodemarker ... all diese Text-BOMs sind dieses Zeichen, nur eben entsprechend kodiert)
ExportText := UTF8Encode(#$FEFF) + ExportText;

z.B. #$0085 ist nicht #$85 ... das hatte mich mal veräppeln wollen :cry:

mjustin 10. Apr 2012 11:33

AW: Textdatei utf8-kodiert speichern!
 
Zitat:

Zitat von Sherlock (Beitrag 1160931)
Delphi-Quellcode:
var ExportText : UTF8String;
    myfStream : TFileStream;
.
.
.
      fExpFileName := fDateiPfad + GUIDohneKlammern + '.xml';
      myfStream := TFileStream.Create(fExpFileName, fmCreate);

      ExportText := #239 + #187 + #191 + ExportText;  // Ist das ausreichend als BOM?

      myfStream.Write(ExportText,Length(ExportText));
Führt zu einer unleserlichen Datei. Muss ich mit dem BOM noch was anderes anstellen? Ist das die Falsche Art den BOM einzufügen?

Sherlock

Wenn es eine XMl Datei ist, kommt es auf das in der Datei enthaltene Encoding-Attribut an. Wenn es nicht angegeben wird, ist es standardmäßig UTF-8. Dann kann auch das BOM komplett entfallen. (Wenn es angegeben wird, muss es mit dem tatsächlichen Encoding übereinstimmen).

Sherlock 10. Apr 2012 12:19

AW: Textdatei utf8-kodiert speichern!
 
mjustin: Das ist absolut korrekt. Nur leider scheint Delphi oder meine Unfähigkeit an der Geschichte etwas zu verwürfeln. Ich tippe übrigens auf letzteres ;)
Ich habe mir jetzt mal die entstandene Datei im Hex-Editor näher angesehen. Es scheint ein Manifest zu sein. Also wird irgendwie die Resource abgespeichert...nicht mein XML-String! :wiejetzt:

Mach ich was grundsätzlich falsch mit dem Stream?
Der auf Seite 1 geposteter Code ist alles, was ich mit dem StreamObjekt treibe.

Sherlock

Sherlock 10. Apr 2012 13:53

AW: Textdatei utf8-kodiert speichern!
 
...und das ist des Rätsels Lösung: Der Sherlock ist dooof. :stupid:

Hier wie man es richtig macht:
Das eigentliche Schreiben:
Delphi-Quellcode:
var DerBOM    : UTF8String;
    ExportText : UTF8String;
.
.
.
      DerBOM := #$00EF#$00BB#$00BF;
      f.WriteBuffer(PAnsiChar(DerBOM)^, Length(DerBOM));  // Könnte man sicher auch in einem Rutsch machen
      f.WriteBuffer(PAnsiChar(exporttext)^, Length(ExportText)); // Aber so gehts definitiv...Unterschied? ZEIGER
Bei der Erzeugung des ExportStrings sollte man im Übrigen immer wieder mal ein UTF8Encode einstreuen...vor allem da, wo Non-ANSI-Zeichen erwartet werden.

Quelle zur letztlichen Lösung (die D2009 voraussetzt, das ich nicht habe): http://mzemaitis.wordpress.com/tag/s...xtfile-delphi/

Sherlock

Bbommel 10. Apr 2012 13:57

AW: Textdatei utf8-kodiert speichern!
 
Hi Sherlock,

noch mal zu den TextFiles. Ich bin da mittlerweile auch ein bisschen von weg, aber habe unter D2007 auch einige Jahre problemlos mit TextFiles/writeln und UTF8 gearbeitet.

Codebeispiel:

Delphi-Quellcode:
procedure Demo;
var s:string;
    fileH: TextFile;
begin
  s:='Ein ü ist ein ü!';
  assignFile(fileH,'egal.txt');
  rewrite(fileH);
  writeln(fileH,utf8encode(s));
  closeFile(fileH);
end;
Damit das reibungslos funktioniert und Delphi nicht intern irgendwas umwandelt, was ich gar nicht will, war es gut, den Text selbst ganz normal als "string" zu benutzen und erst am Ende beim writeln mit "utf8encode" umzuwandeln.

Alternativ geht das gleiche auch mit TStringList, also:
Delphi-Quellcode:
[...}
StrList.Add(utf8encode(s));
StrList.SaveToFile('egal.txt');
[...]
Und wenn du auf Delphi >=2009 umsteigst, musst du den Code eh wieder anfassen. ;)

Sherlock 10. Apr 2012 14:06

AW: Textdatei utf8-kodiert speichern!
 
Grrmml...hättest Du das nicht vor 4 Stunden schreiben können? :lol:

Egal, jetzt stehen hier für zukünftige Generationen zwei Lösungen ;)

:dp:

Sherlock

Bernhard Geyer 10. Apr 2012 14:30

AW: Textdatei utf8-kodiert speichern!
 
Zitat:

Zitat von Sherlock (Beitrag 1160974)
Grrmml...hättest Du das nicht vor 4 Stunden schreiben können? :lol:

Egal, jetzt stehen hier für zukünftige Generationen zwei Lösungen ;)

:dp:

Sherlock

Wie Bbommel schon geschrieben hast ist das keine Lösung "für zukünfitge Generationen".

In "zukunft" (D2009+) reicht ein

Delphi-Quellcode:
StrList.SaveToFile('egal.txt', TEncoding.UTF8);

Bbommel 11. Apr 2012 07:56

AW: Textdatei utf8-kodiert speichern!
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1160989)
Wie Bbommel schon geschrieben hast ist das keine Lösung "für zukünfitge Generationen".

Das stimmt natürlich für die StringList. Aber auch wenn readln/writeln hier immer eher einen schlechten Ruf genießen :), sei noch erwähnt, dass man das obige Beispiel mit writeln auch unter XE2 noch genau so benutzen kann. Nur wenn man dann UTF8-Dateien mit readln lesen wollen würde, müsste man basteln (das Stichwort RawByteString fiel ja schon).

Und wenn das zukünftige Suchende finden, sollte aber auch noch erwähnt werden, dass beide Beispiele von mir keinen BOM schreiben. Der müsste, falls benötigt, dann noch manuell davor ergänzt werden.

Bis denn
Bommel


Alle Zeitangaben in WEZ +1. Es ist jetzt 00: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