AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte TTextStream - Textdateien einlesen
Thema durchsuchen
Ansicht
Themen-Optionen

TTextStream - Textdateien einlesen

Ein Thema von himitsu · begonnen am 19. Mai 2010 · letzter Beitrag vom 4. Nov 2011
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    
Benutzerbild von himitsu
himitsu
Registriert seit: 11. Okt 2003
So, den nun hab ich erstmal den Schreib-/Lesekern meiner neuen StringListe seppariert und er läuft endlich.
Manchmal muß man eben mit mehrfachem Code leben ... hartkodierte Konstanten sind eben schneller, als Variablen und eine dynamische Verarbeitung.

Diese Klasse ließt eine beliebig große Textdatei sequentiell ein, wobei sogar unterschiedliche Kodierungen (TEncoding) unterstützt werden und ein eventuelles BOM ausgewertet wird.
Speichern ist natürlich auch möglich.

Nja, die Speicherverwaltung des Lesepuffers gefällt mir noch nicht so ganz
( http://www.delphipraxis.net/internal...t.php?t=177739 ),
aber für diesen Fall dürfte es denoch ausreichend sein.

Ja nach Datei und Computer ist es etwa gleichschnell oder schneller als eine TStringList zu Einlesen braucht (wobei die TStringList irgendwann an ihre Speichergrenzen stößt, da sie alles im Arbeitsspeicher verarbeitet, welches beim Einlesen einer einfachen Ansi-Datei in Delphi2009/2010 mehr als den 4-fachen Speicherbearf, der ursprünglichen Dateigröße verlangt)



Als Zusatzmodul ist mir eingefallen, daß man die (ur)alten Pascal-Datei-Funktionen ersetzen könnte,
aber leider ist es nicht möglich einen adequaten Ersatz für Read, ReadLn, Write und WriteLn zu finden ,
Aber vielleicht hat ja jemand eine brillante Erleuchtung.


PS: Der Name "TStringStreamEx" der Klasse gefällt mir eigentlich auch nicht, aber irgendwer hatte schon die Idee eine andere Klasse TStringStream zu nennen.

[edit] Name angenommen

[edit 20.05.2010]
  • alles etwas überarbeitet
  • eine Version für Delphis vor 2009 erstellt
    Als Bonus hat sie eine einfache Variante des TEncoding bekommen, welches man natürlich auch für andere Dinge nutzen könnte.
  • und Zusatzmodul TTextStreamEx fertiggestellt

[edit 21.05.2010 v1.2c]
Wo es nun zu laufen scheint, hab ich mir mal die Unterschiede angesehn
und beide Versionen miteinander kombiniert.

Außerdem hatte ich glatt was vergessen zu übernehmen.
Beim Einlesen einer Datei werden die Zeilenumbrüche analysiert und das Property LineBreak enthält dann den häufigsten Zeilenumbruch (falls es mal ein bissl gemischt ist) ... die FileStringList wird somit später den Zeilenumbruch einer Datei quasi erhalten und ihn nicht ständig auf Windowsstandard (CRLF) abändern.

[edit 17.08.2010 v1.3]
- BOM-Erkennung bei Angabe einer Kodierung integriert
- BOM kann nun beim Schreiben weggelassen werden

[edit 18.10.2010 v1.4a2]
- neue Testversion (sie Beitrag #31)
Angehängte Dateien
Dateityp: pas TextStream v1.2c 21.05.2010.pas (51,2 KB, 92x aufgerufen)
Dateityp: pas TextStream.pas (51,5 KB, 132x aufgerufen)
Dateityp: pas TextStream v1.4 alpha2 18.10.2010.pas (52,8 KB, 156x aufgerufen)
$2B or not $2B

Geändert von himitsu (18. Okt 2010 um 16:21 Uhr)
 
Namenloser

 
FreePascal / Lazarus
 
#2
  Alt 19. Mai 2010, 20:53
Nur kurz zur Namensgebung:
Zitat von himitsu:
PS: Der Name "TStringStreamEx" der Klasse gefällt mir eigentlich auch nicht, aber irgendwer hatte schon die Idee eine andere Klasse TStringStream zu nennen.
Wie wäre es mit TTextStream?

[edit]BBCode gefixt[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von gsh
gsh

 
Delphi XE Architect
 
#3
  Alt 20. Mai 2010, 11:57
Hallo himitsu,

nette Klasse hast du da erstellt. Wollte sie mal ausprobieren aber mir fehlen leider folgende Typen:
TEncoding, TBytes, TMBCSEncoding

Habe die Classes, SysUtils bereits eigebunden ... aber keine Unit für die oberen Typen gefunden. (Sind die vielleicht von dir?)

Danke
gsh
Alex
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

 
Delphi 12 Athens
 
#4
  Alt 20. Mai 2010, 12:01
Das ist vermutlich wieder alles Unicode-Gedöns (zumindest TEncoding), also erst ab D2009 zu gebrauchen.
Detlef
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#5
  Alt 20. Mai 2010, 12:04
@DeddyH
Noar, also ab Delphi 2009 ... aber man könnte sich notfalls auch einen Dummy für TEncoding erstellen und dann dürfte es auch in älteren Delphis laufen.

TEncoding hatte ich eben genommen, da es "aktuell" auch in der VCL verwendet wird und somit leichter benutzbar ist
, außerdem befindet sich somit kein Code für eine En-/Decodierung im eigenen Projekt und es kann alles extern verarbeitet werden.

TBytes ist einfach nur ein Array of Byte.

[add]
Ich mach jetzt nur noch schnell was Anderes fertig und dann versuch ich es mal in TDE zum Laufen zu bekommen.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

 
FreePascal / Lazarus
 
#6
  Alt 20. Mai 2010, 13:56
Zitat von himitsu:

Als Zusatzmodul ist mir eingefallen, daß man die (ur)alten Pascal-Datei-Funktionen ersetzen könnte,
aber leider ist es nicht möglich einen adequaten Ersatz für Read, ReadLn, Write und WriteLn zu finden :cry:,
Write und Writeln sind doch recht einfach durch ein Blockwrite(Datei,satz[1],sizeof(satz)) bzw. seiner TStream-Entsprechung zu ersetzen. Fummelig ist nur der Unterschied zwischen length() und sizeof() in den Griff zu kriegen.

für ein Read (bei "Text - Dateien") sehe ich eigentlich keine Verwendung (wer braucht schon ein Read(char)).
Beim Readln kommt man um das scannen nach dem EOL nicht herum, dafür kann man dann auch frei definieren wodurch EOL gekennzeichnet ist (CRLF, LFCR, CR, LF, #0.....)
Und man baut noch gleich einen Interpreter für die alten ANSI-Codes mit ein (!?)
Und das alles natürlich frei definierbar......
Ach ja bei der Gelegenheit kann man gleich noch BigEndian und LittleEndian berücksichtigen......

;-))



Gruß
K-H
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#7
  Alt 20. Mai 2010, 15:00
Zitat von p80286:
Write und Writeln sind doch recht einfach ...
Nja, es geht mehr um sowas schön Kombiniertes wie ReadLn(i, S).
WriteLn(123, i, 'ads', s) kann man ja notfalls durch WriteLn([...]) ersetzen.

Zitat von p80286:
Und man baut noch gleich einen Interpreter für die alten ANSI-Codes mit ein (!?)
Und das alles natürlich frei definierbar......
Ach ja bei der Gelegenheit kann man gleich noch BigEndian und LittleEndian berücksichtigen.....
Das macht doch alles schon das nette TEncoding
und der "Parser" sollte sowas auch beachten.

So, ein Art kombiniertes Write/WriteLn gibt es, aber natülich nicht das Read/ReadLn.
Read ließt nur einen Wert, der aktuellen Zeile und EoLn gibt an, ob es noch weitere Werte in der aktuellen Zeile gibt.
(praktisch fast genauso, wie bei den alten Pascalfunktionen)

Diese Textzeile
Code:
132 abc true
könnte man also folgendermaßen auslesen
Delphi-Quellcode:
F.Read(int);
F.Read(str);
F.Read(bool);
oder 'ne ganze Datei gleich mal so ... Wert für Wert:
Delphi-Quellcode:
F := TTextStreamEx.Create('Datei.txt', saRead);
Try
  While not EoF do Begin
    While not EoLn do
      ShowMessage(ReadString);
    ReadLn;
  End;
Finally
  F.Free;
End;
Ja, und ich hoffe mal die Vor2009-Variante läuft gut.
Als Bonus hat sie eine einfache Variante des TEncoding bekommen, welches man natürlich auch für andere Dinge nutzen könnte.
  Mit Zitat antworten Zitat
Benutzerbild von gsh
gsh

 
Delphi XE Architect
 
#8
  Alt 20. Mai 2010, 16:02
Zitat von himitsu:
Ja, und ich hoffe mal die Vor2009-Variante läuft gut.
Als Bonus hat sie eine einfache Variante des TEncoding bekommen, welches man natürlich auch für andere Dinge nutzen könnte.
Danke für das "Update".
Gleich mal als erstes: Zeile 259 steht einfach das Wort CompilerVersion ... was da sicher nicht hingehört und ws ein "Strg+V Fehler" ist
Dann wollte ich noch sagen das ich unter D2006 folgende Hinweise und Warnungen erhalte:
Zitat:
[Pascal Warnung] TextStreamNUC.pas(479): W1050 WideChar in Set-Ausdrücken auf ByteChar verkürzt
[Pascal Hinweis] TextStreamNUC.pas(525): H2077 Auf 'i' zugewiesener Wert wird niemals benutzt
[Pascal Warnung] TextStreamNUC.pas(806): W1050 WideChar in Set-Ausdrücken auf ByteChar verkürzt
[Pascal Hinweis] TextStreamNUC.pas(894): H2077 Auf 'Value' zugewiesener Wert wird niemals benutzt
[Pascal Warnung] TextStreamNUC.pas(928): W1044 Bedenkliche Typumwandlung von WideString in PAnsiChar
[Pascal Hinweis] TextStreamNUC.pas(952): H2077 Auf 'Value' zugewiesener Wert wird niemals benutzt
[Pascal Warnung] TextStreamNUC.pas(986): W1044 Bedenkliche Typumwandlung von WideString in PAnsiChar
[Pascal Warnung] TextStreamNUC.pas(1040): W1044 Bedenkliche Typumwandlung von WideString in PAnsiChar
[Pascal Warnung] TextStreamNUC.pas(1146): W1035 Rückgabewert der Funktion 'TTextStreamEx.ReadBool' könnte undefiniert sein
[Pascal Warnung] TextStreamNUC.pas(1200): W1035 Rückgabewert der Funktion 'TTextStreamEx.ReadLnBool' könnte undefiniert sein
Werde dann gleich mal die Funktionalität testen.
Alex
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 12 Athens
 
#9
  Alt 20. Mai 2010, 16:24
Zitat von gsh:
Gleich mal als erstes: Zeile 259 steht einfach das Wort CompilerVersion ... was da sicher nicht hingehört und ws ein "Strg+V Fehler" ist
Ups

Zitat:
W1050 WideChar in Set-Ausdrücken auf ByteChar verkürzt
Dieses kannst'e ignorieren.

Ansonsten hoff' ich mal, daß die anderen Meldungen nun weg sind.


Zitat:
Bedenkliche Typumwandlung von WideString in PAnsiChar
Dieses war 'ne übereifrige Ersetzungaktion ... der Code hätte eigentlich unverändert bleiben können
(also String und PChar unverändert ... im restlichen Code mußte es aber nach WideString geändert werden)

Zitat:
Rückgabewert der Funktion ... könnte undefiniert sein
blöde vergessene VAR, im Parameter
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

 
FreePascal / Lazarus
 
#10
  Alt 20. Mai 2010, 17:14
Zitat von himitsu:
Diese Textzeile
Code:
132 abc true
könnte man also folgendermaßen auslesen
Delphi-Quellcode:
F.Read(int);
F.Read(str);
F.Read(bool);
Ihr kommt auf Ideen, solche Perversitäten, hab ich früher immer mit Records und festen Satzlängen erschlagen.
(die Großrechner-Schädigung kommt eben immer wieder durch)

und bevor es jemand anmerkt, die Konsole hab ich immer mit repeat until keypressed; read(inkey) bedient. Ein schnödes readln(konsolendaten) ist mir sehr selten über den Weg gelaufen.

Gruß
K-H
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    


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 02: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