Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   TStringList ohne BOM speichern? (https://www.delphipraxis.net/178328-tstringlist-ohne-bom-speichern.html)

fillibuster 2. Jan 2014 08:26

Delphi-Version: 2010

TStringList ohne BOM speichern?
 
Hi,

gibt es eine einfache Möglichkeit (D2010) das BOM nicht mitzuschreiben? Meine erstellten StringListen speichere ich so:
Delphi-Quellcode:
sl.SaveToFile(savepath + 'muster.txt',TEncoding.UTF8);

Vielen Dank!

Furtbichler 2. Jan 2014 08:40

AW: TStringList ohne BOM speichern?
 
Wer sollte das dann wieder einlesen können? Der BOM für UTF-8 hat schon seinen Sinn. Was stört dich daran?

Perlsau 2. Jan 2014 08:51

AW: TStringList ohne BOM speichern?
 
Moin Furtbichler, ein gutes Neues wünsche ich.

Z.B. meckert der Firebird-Script-Editor, wenn ich ein mittels StringListe erstelltes SQL-Script einlesen will, dem ein BOM vorangestellt ist. Liegt vielleicht aber auch an den Einschränkungen der Personal-Version :?

fillibuster 2. Jan 2014 08:53

AW: TStringList ohne BOM speichern?
 
Hallo - äh genau und frohes neues Jahr,

ich schreibe damit PHP Scripte und PHP hat die unschöne Eigenart bei einem Script mit BOM einen headers already sent Fehler zu produzieren.

Viele Grüße ...

Bernhard Geyer 2. Jan 2014 08:55

AW: TStringList ohne BOM speichern?
 
Wenn unbedingt sein muss bastel dir eine Hilfsfunktion indem du die Stringlist erst in einen stream Speicherst und dann die ersten 3 Byte beim Speichern weg lässt.

@Furtbichler: Ich kenne öfter den Fall das "Hochqualifizierte" ERP bzw. PLM-Entwickler es nicht schaffen in Exportdateien solch einen BOM zu schreiben (Man muss öfter schon froh sein das Sonderzeichen korrekt geschrieben werden). Dann haben Sie auch vermutlich oft das Problem so einen BOM lesen und korrekt interpretieren zu können.

Uwe Raabe 2. Jan 2014 09:17

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von fillibuster (Beitrag 1241706)
gibt es eine einfache Möglichkeit (D2010) das BOM nicht mitzuschreiben?

  1. Update auf XE oder höher
  2. Delphi-Quellcode:
    sl.WriteBOM := false;

Perlsau 2. Jan 2014 09:18

AW: TStringList ohne BOM speichern?
 
Hab eben mal zum Testen zwei Textdateien erstellt, einmal via Liste.SaveToFile(Datei) und einmal via Liste.SaveToFile(Datei,TEncoding.UTF8). Wenn ich die mit PsPad öffne, wird mir dort für beide Dateien das Format UTF8 angezeigt.

Gehe ich recht in der Annahme, daß ab Delphi 2009 standardmäßig im UTF8-Format gespeichert wird, wenn nichts anderes angegeben wurde? Die Datei mit dem Bom ist nur unerheblich größer als die andere.

Uwe Raabe 2. Jan 2014 09:21

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1241717)
Zitat:

Zitat von fillibuster (Beitrag 1241706)
gibt es eine einfache Möglichkeit (D2010) das BOM nicht mitzuschreiben?

  1. Update auf XE oder höher
  2. Delphi-Quellcode:
    sl.WriteBOM := false;

OK, sollte Punkt 1 zu große Schwierigkeiten bereiten, kannst du auch eine eigene Klasse von TUTF8Encoding ableiten, dort GetPreamble überschreiben und ein leeres TBytes zurückgeben. Du musst dich dann bloß selbst um Instanziierung und Freigabe des Encoding-Objekts kümmern.

fillibuster 2. Jan 2014 09:29

AW: TStringList ohne BOM speichern?
 
Hallo,

danke für die Antworten. Werde ich dann wohl selbst Hand anlegen. Eine Sache noch in diesem Zusammenhang. In den gespeicherten Dateien ist immer eine (Leer)Zeile mehr drin als eigentlich geschrieben wird. Liegt das auch am BOM?

Viele Grüße ...

MaBuSE 2. Jan 2014 09:37

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von fillibuster (Beitrag 1241706)
gibt es eine einfache Möglichkeit (D2010) das BOM nicht mitzuschreiben? Meine erstellten StringListen speichere ich so:
Delphi-Quellcode:
sl.SaveToFile(savepath + 'muster.txt',TEncoding.UTF8);

TStrings hat eine Eigenschaft WriteBOM.

Per Default ist die auf True.

Beisp:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Lines.WriteBOM := True;
  memo1.Lines.SaveToFile('z:\temp\1.txt', TEncoding.UTF8);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Lines.WriteBOM := False;
  Memo1.Lines.SaveToFile('z:\temp\2.txt', TEncoding.UTF8);
end;

DeddyH 2. Jan 2014 09:38

AW: TStringList ohne BOM speichern?
 
Das hatte Uwe aber bereits erwähnt ;)

Uwe Raabe 2. Jan 2014 09:38

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von MaBuSE (Beitrag 1241725)
TStrings hat eine Eigenschaft WriteBOM.

Nicht in D2010!

Tonic1024 2. Jan 2014 09:39

AW: TStringList ohne BOM speichern?
 
Zitat:

In den gespeicherten Dateien ist immer eine (Leer)Zeile mehr drin als eigentlich geschrieben wird.
Nein, das ist völlig normales Verhalten. Am Ende einer jeden Zeile der Liste ist automatisch ein Zeilenumbruch. Nur in den Köpfen der Programmierer macht es Sinn nach der letzten Zeile keinen Zeilenumbruch haben zu wollen. Bin selbst mal drauf herein gefallen.

Entweder man hat nach jeder Zeile, auch der Letzten, automatisch ein #13#10 oder man kümmert sich von Anfang an selbst drum. Macht durchaus Sinn - falls du das gemeint hast.

Gruß,

Toni

MaBuSE 2. Jan 2014 09:40

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von DeddyH (Beitrag 1241726)
Das hatte Uwe aber bereits erwähnt ;)

Danke das hatte ich dann auch gesehen.
Man sollte vor dem Posten noch mal einen Refresh machen :oops:

Sir Rufo 2. Jan 2014 09:41

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1241727)
Zitat:

Zitat von MaBuSE (Beitrag 1241725)
TStrings hat eine Eigenschaft WriteBOM.

Nicht in D2010!

Jenau

TStrings (D2010 Doku)
TStrings (XE Doku)

Perlsau 2. Jan 2014 09:50

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Tonic1024 (Beitrag 1241728)
Nein, das ist völlig normales Verhalten. Am Ende einer jeden Zeile der Liste ist automatisch ein Zeilenumbruch. Nur in den Köpfen der Programmierer macht es Sinn nach der letzten Zeile keinen Zeilenumbruch haben zu wollen. Bin selbst mal drauf herein gefallen.

Diese "letzte Zeile" wird beim Öffnen via Liste.LoadFromFile jedoch nicht mit eingelesen, wie ich eben ermittelt habe: In meiner Testdatei befinden sich laut PsPad 23.971 Zeilen incl. der letzten, leeren Zeile, die ja nur aus 0D0A (#13+#10) besteht. Beim Einlesen derselben Datei via Liste.LoadFromFile erhalte ich jedoch nur 23.970 Zeilen.

Bernhard Geyer 2. Jan 2014 10:14

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1241717)
  1. Update auf XE oder höher
  2. Delphi-Quellcode:
    sl.WriteBOM := false;

Danke für die Info. Dann braucht man hier nix mehr selbst machen (bzw. bei Update auf neue Version evtl. Altcode entsorgen).

himitsu 2. Jan 2014 10:41

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Furtbichler (Beitrag 1241709)
Wer sollte das dann wieder einlesen können? Der BOM für UTF-8 hat schon seinen Sinn. Was stört dich daran?

Es kommt drauf an.
Bestimmte Dateiformate haben eine andere Standardformatierung, wenn kein BOM vorhanden ist.
z.B. XML ist standardmäßig UTF-8

Und auch bei HTML muß die Kodierung nicht als BOM drinstehen, sondern wird über Meta-Tags definiert.


PS: Im Notfall hätte man sich auch ganz einfach ein eigenes TEncoding definieren können, welches kein BOM enthält.
Delphi-Quellcode:
TMBCSEncoding.Create(CP_UTF8)

p80286 2. Jan 2014 10:55

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Tonic1024 (Beitrag 1241728)

Entweder man hat nach jeder Zeile, auch der Letzten, automatisch ein #13#10 oder man kümmert sich von Anfang an selbst drum. Macht durchaus Sinn - falls du das gemeint hast.

Das ist durch die Historie bedingt. "CarriageReturn, Linefeed" war für viele Drucker und Monitore die Ansteuerung für eine neue Zeile. Jetzt kommt es darauf an was Du willst, eine neue Zeile nach Deinem Text oder aber nicht, dementsprechend ein x0D0A oder nicht.
Es gibt/gab ja auch Programme die eine Textdatei mit einem x0D0A121A beendet haben.

Alles eine Frage der Konvention.

Gruß
K-H

Tonic1024 2. Jan 2014 12:00

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Perlsau (Beitrag 1241733)
Diese "letzte Zeile" wird beim Öffnen via Liste.LoadFromFile jedoch nicht mit eingelesen, wie ich eben ermittelt habe: In meiner Testdatei befinden sich laut PsPad 23.971 Zeilen incl. der letzten, leeren Zeile, die ja nur aus 0D0A (#13+#10) besteht. Beim Einlesen derselben Datei via Liste.LoadFromFile erhalte ich jedoch nur 23.970 Zeilen.

Ist letztlich Auslegungssache. In meinen Augen ist #13#10 nicht eine neue Zeile, sondern es steht am Ende der letzten, mit text gefüllten Zeile. So wie in jeder Zeile vorher.

Der Cursor blinkt nach einem LineFeed allerdings korrekter Weise am Anfang einer (noch) nicht existenten zusätzlichen Zeile. Der XY-Positionsanzeiger des Cursors zeigt dann folgerichtig natürlich eine Zeile mehr an. Diese wird dann natürlich aber nicht mit gespeichert, weil das ja ein zusätzliches #13#10 (im Stream also ein #13#10#13#10) zur Folge hätte. Mehrfaches Laden und Speichern würde jetzt je eine Zeile mehr erzeugen und die Datei würde wachsen, wachsen, wachsen.

Über die Darstellung kann man sich jetzt natürlich streiten. Technisch betrachtet ist es in meinen Augen aber korrekt wie es ist. Nur im Kopf ist es auf den ersten Blick irgendwie unlogisch.

Perlsau 2. Jan 2014 12:18

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Tonic1024 (Beitrag 1241767)
Ist letztlich Auslegungssache. In meinen Augen ist #13#10 nicht eine neue Zeile, sondern es steht am Ende der letzten, mit text gefüllten Zeile. So wie in jeder Zeile vorher.

Aus Sicht eines Programmierers ist das vollkommen korrekt. Aus Sicht eines reinen Anwenders, insbesondere eines DAUs, der absolut nichts von irgendwelchen Internas weiß, zählt das, was sein Programm anzeigt. Somit hast du recht: es kommt drauf an, wer die Sache deutet.

Zitat:

Zitat von Tonic1024 (Beitrag 1241767)
Der Cursor blinkt nach einem LineFeed allerdings korrekter Weise am Anfang einer (noch) nicht existenten zusätzlichen Zeile. Der XY-Positionsanzeiger des Cursors zeigt dann folgerichtig natürlich eine Zeile mehr an. Diese wird dann natürlich aber nicht mit gespeichert, weil das ja ein zusätzliches #13#10 (im Stream also ein #13#10#13#10) zur Folge hätte. Mehrfaches Laden und Speichern würde jetzt je eine Zeile mehr erzeugen und die Datei würde wachsen, wachsen, wachsen.

Auch das ist korrekt, denn hier betrachtest du die Sache aus der Sicht eines Programmierers.

Zitat:

Zitat von Tonic1024 (Beitrag 1241767)
Über die Darstellung kann man sich jetzt natürlich streiten. Technisch betrachtet ist es in meinen Augen aber korrekt wie es ist. Nur im Kopf ist es auf den ersten Blick irgendwie unlogisch.

Ich kann daran nichts Unlogisches erkennen: Viele Textanzeige-Programme, die ich kenne, zeigen nach dem Zeilenende eine neue Zeile an. Aus Sicht des Programmierers existiert die zwar nicht, aus Sicht des Anwenders aber schon, denn der kann direkt an der neuen Cursorposition Text eingeben. Bei RTF- und Wörd-Dateien ist das anders, aber das betrifft eben nur die Darstellung bzw. die Anwendungslogik.

Somit dürfte nun auch die Frage aus Nummer 9 erschöpfend beantwortet sein :stupid:

fillibuster 2. Jan 2014 12:35

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Perlsau (Beitrag 1241772)
...
Somit dürfte nun auch die Frage aus Nummer 9 erschöpfend beantwortet sein :stupid:

ich denke auch :thumb:

Perlsau 2. Jan 2014 13:10

AW: TStringList ohne BOM speichern?
 
Dennoch würde ich gerne noch einmal auf meine Frage in Post Nummer 7 zurückkommen:

In welchem Format wird gespeichert, wenn ich keinen Encoding-Parameter angebe?

DeddyH 2. Jan 2014 13:17

AW: TStringList ohne BOM speichern?
 
http://docwiki.embarcadero.com/Libra...ngs.SaveToFile:
Zitat:

Wenn der Parameter Encoding nicht angegeben ist, werden die Strings mit der in der Eigenschaft Encoding angegebenen Codierung gespeichert.
http://docwiki.embarcadero.com/Libra...rings.Encoding:
Zitat:

Encoding ist eine schreibgeschützte Eigenschaft, die den Wert der Codierung enthält, die beim Aufrufen der Methoden LoadFromStream oder LoadFromFile gefunden wird. Wenn die Datei kein BOM enthält, kann der Wert der Codierung nicht gefunden werden und Encoding wird auf die in der Eigenschaft DefaultEncoding angegebene Standardcodierung gesetzt.
Steht alles in der Doku.

MaBuSE 2. Jan 2014 13:18

AW: TStringList ohne BOM speichern?
 
Zitat:

Zitat von Perlsau (Beitrag 1241778)
In welchem Format wird gespeichert, wenn ich keinen Encoding-Parameter angebe?

Je nachdem, das in TEncoding.Default steht ;-)

Wobei die TStrings ab Delphi XE ja auch eine DefaultEncoding Eigenschaft hat.
Delphi-Quellcode:
  Memo1.Lines.DefaultEncoding; // sollte TEncoding.Default sein
  Memo1.Lines.Encoding; // wird beim Laden gesetzt, per Default auf DefaultEncoding
  Memo1.Lines.SaveToFile('x');
Laut Doku: ( http://docwiki.embarcadero.com/Libra...coding.Default )
Code:
System.SysUtils.TEncoding.Default

Platfform     Standardcodierung   Instanz
-------------  -------------------  ---------------------------------------
Windows       ANSI                System.SysUtils.TMBCSEncoding
Mac OS X      UTF-8                System.SysUtils.TUTF8Encoding


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:33 Uhr.

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