Delphi-PRAXiS
Seite 2 von 5     12 34     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   TTextStream - Textdateien einlesen (https://www.delphipraxis.net/151481-ttextstream-textdateien-einlesen.html)

himitsu 20. Mai 2010 18:29

Re: TStringStreamEx - Textdateien einlesen
 
Zitat:

Zitat von p80286
Ihr kommt auf Ideen, solche Perversitäten,

*rrrrrrrr*

Manchmal sind die alten Pascal-Funktionen eigentlich recht praktisch.
Nur schade ist, daß man damit nur ANSI-Text-Dateien erstellen und auslesen kann
und das interne Caching ist nicht unbedingt .... nja, ich wie soll man es denn nennen? ... optimal?

Hiermit könnte man sogar eine normale TStringList effektiver füllen. Zumindestens was größere Dateien angeht, dann so ab einer 300 MB-Textdatei bekommt man schonmal ein OutOfMemory, da ja alles am Stück eingelesen und verarbeite wird, also wärend des LoadFrom... und SaveTo....

himitsu 21. Mai 2010 08:56

Re: TTextStream - Textdateien einlesen
 
[info] nicht wundern ... es gibt jetzt nur noch eine Version für Unicode (D2009/2010) und die anderen Delphis.

Nja, und ein paar vergessene Codezeilen wurden noch schnell integriert ... die Erkennung der Zeilenumbrüche (siehe [edit] in #1).

chaosben 21. Mai 2010 11:32

Re: TTextStream - Textdateien einlesen
 
Fein gemacht! :thumb:

Ein Verbesserungsvorschlag für Zeile 707:
Delphi-Quellcode:
Else Mode := fmOpenReadWrite or fmShareDenyWrite or fmCreate;
Ohne dem dem fmCreate machts bei neuen Dateien einfach nur buuuuuuum. ;)

himitsu 21. Mai 2010 12:09

Re: TTextStream - Textdateien einlesen
 
Ups, also für Zeile 706+707 dann Dieses:
Delphi-Quellcode:
If     Access = saRead  Then Mode := fmOpenRead     or fmShareDenyWrite
Else If Access = saAppend Then Mode := fmOpenReadWrite or fmShareDenyWrite
Else              Mode := fmCreate or fmOpenReadWrite or fmShareDenyWrite;
Im Testcode lese ich über einen Stream ein und schreibe auch darüber. Und dort wird über CreateFile + einen speziellen THandleStream gearbeitet ... da ist dieser CodeTeil wohl etwas zukurzgeraten, beim Test. :oops:


Hier knallt's nicht, aber es ist schon blöd, daß man dem TFileStream nicht weitere Attribute mitgeben kann :cry: (vorallem FILE_FLAG_RANDOM_ACCESS und FILE_FLAG_SEQUENTIAL_SCAN geb ich ja gerne mal an, um Windows ein bissl unter die Arme zu greifen)
Delphi-Quellcode:
Case Mode of
  fmReadWrite: Begin
                  A := GENERIC_READ or GENERIC_WRITE;
                  C := OPEN_EXISTING;
                End;
  fmCreate:    Begin
                  A := GENERIC_READ or GENERIC_WRITE;
                  C := CREATE_NEW;
                  Mode := fmReadWrite;
                End;
  fmCreateOrRW: Begin
                  A := GENERIC_READ or GENERIC_WRITE;
                  C := OPEN_ALWAYS;
                  Mode := fmReadWrite;
                End;
  Else         Begin
                  A := GENERIC_READ;
                  C := OPEN_EXISTING;
                End;
End;
H := CreateFile(PChar(Filename), A, FILE_SHARE_READ, nil, C,
  FILE_FLAG_RANDOM_ACCESS or FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, 0);
If H = INVALID_HANDLE_VALUE Then
  Raise EFCreateError.CreateResFmt(@SFCreateErrorEx,
    [ExpandFileName(Filename), SysErrorMessage(GetLastError)]);
AssignToStream(THandleStream2.Create(H), True, Mode = fmReadOnly, Encoding);
Mal sehn, vielleich verbau ich noch 'ne Abwandlung davon in diesem Code. :gruebel:

chaosben 21. Mai 2010 13:02

Re: TTextStream - Textdateien einlesen
 
Dann habe ich noch ein Problem ... beim Flush im Destructor eines schreibenden (logisch :) ) TTextStreams kommt eine Zugriffverletzung an der Stelle
Delphi-Quellcode:
FByteBuffer := FEncoding.GetBytes(FStringBuffer);
in der Funktion "WideCharToMultiByte".

Ich gebe zu, dafür kannst du wahrscheinlich nicht direkt was, aber falls dir eine Lösung einfällt, würde ich mich freuen. :)

Das hier funktioniert nicht:
Delphi-Quellcode:
procedure TForm30.FormCreate(Sender: TObject);
var
  tt : TTextStream;
begin
  tt := TTextStream.Create('f:\test.txt', saWrite);
  tt.WriteLine(DateTimeToStr(Now));
  tt.Free;

end;
Das gleiche in einer ConsolenApp geht [edit]auch nicht[/edit]. :wall:

himitsu 21. Mai 2010 13:20

Re: TTextStream - Textdateien einlesen
 
Oh, da hat sich noch ein Fehler bei der Pufferumstellung eingeschlichen
(früher Byte-Array mit 0-Index und jetzt String mit der bösen 1, aber die anderen Codestellen sehen diesbezüglich OK aus :angel2: )

Zeile 811
Code:
[b]Procedure[/b] TTextStream.WritePart(Const S: SString);
  [b]Begin[/b]
    ...
      Move(S[1], FStringBuffer[FBufferSize[color=#ff0000][b] + 1[/b][/color]], Length(S) * SizeOf(Char));
und Zeile 836
Code:
[b]Procedure[/b] TTextStream.Flush;
  [b]Begin[/b]
    [b]If[/b] FAccess <> saRead [b]Then Begin[/b]
      FByteBuffer := FEncoding.GetBytes([color=#ff0000][b]Copy([/b][/color]FStringBuffer[color=#ff0000][b], 1, FBufferSize)[/b][/color]);
Aber schon witzig, daß es dennoch manchmal problemlos läuft. :shock:

Zitat:

Zitat von chaosben
[edit]auch nicht[/edit]. :wall:

manchmal schon :lol:


Zum Glück muß ich Fehler jetzt nur noch in einer Version fixen :-D

chaosben 21. Mai 2010 21:01

Re: TTextStream - Textdateien einlesen
 
Vielen Danke fürs fixen. :dp:

freejay 17. Aug 2010 10:53

AW: TTextStream - Textdateien einlesen
 
Hi Himitsu,

ich benutze Deine Unit TextStream und habe dabei ein Problem und eine weitere Frage:

1. Wenn man eine Datei einliest, die UTF-8 codiert ist (mit! BOM), dann erhält man in der ersten Zeile als erstes "Zeichen" immer $FEFF (65279). Dies passiert nur, wenn man als Encoding beim Öffnen (=Create) TEncoding.UTF8 angibt. Lässt man das Encoding weg (nil), funktioniert es korrekt. Was kann man da machen?

2. Es scheint mir mit Deiner Unit nicht möglich zu sein eine UTF-8 codierte Datei ohne! BOM zu erzeugen, oder habe ich da etwas übersehen?

Danke in Voraus

Freejay

himitsu 17. Aug 2010 13:07

AW: TTextStream - Textdateien einlesen
 
Joar, da hatte ich wohl ein bissl zuviel gelöscht.

1. sollte jetzt funktionieren.
(die Prüfung wurde ausversehn mit entfernt)

2. joar, das war hier eigentlich nicht vorgesehn
(in meiner größeren Version gibt es dafür eine interne Option ... hab dafür aber nun einen neuen Access-Wert eingeführt > saWriteWithoutBOM)


#$FEFF ist das "Zeichen" für Unicode ... wenn man dieses Zeichen entsprechend kodiert, dann ergibt dieses das BOM der zugehörigen Kodierung. :angel:

ChrisE 17. Aug 2010 13:47

AW: TTextStream - Textdateien einlesen
 
Hallo,

erstmal TOP :thumb:

Hab beim Überfliegen gerade gesehen, dass sich u.U. ein Copy&Paste-Fehler eingeschlichen hat. In Zeile 287-289 von
Delphi-Quellcode:
Class Function TEncoding.GetASCII: TEncoding;
wird
Delphi-Quellcode:
FBigEndianUnicodeEncoding
verwendet anstatt wahrscheinlich
Delphi-Quellcode:
FASCIIEncoding
.

Ist aber nur eine Vermutung.

Gruß, Chris


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:37 Uhr.
Seite 2 von 5     12 34     Letzte »    

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