Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zeilen von einem Stream lesen (https://www.delphipraxis.net/126497-zeilen-von-einem-stream-lesen.html)

danieleh 26. Dez 2008 12:02


Zeilen von einem Stream lesen
 
Hallo
Ich benutze momentan die Methode von Hawkeye219 im Beitrag: http://www.delphipraxis.net/internal...tfilestreamext
um Strings (von einem Memo) in einen Stream zu lesen/schreiben.

Frage: wie kann man einzelne Zeilen direkt aus dem Stream lesen ? (ohne den Umweg über den gesamten Stream in ein Memo zu laden)

Wäre sehr Dankbar für Eure Hilfe.
Daniele

andreash 26. Dez 2008 13:56

Re: Zeilen von einem Stream lesen
 
Hallo,

ich habe gerade gestern mit Streams als Textfile experimentiert. Hier mein erster Versuch. Einfach eine Variable vom Typ Textfile mit dem gewünschtem Stream mit StreamFile.AssignFile initialisieren und mit Reset öffnen, dann geht es gewohnt weiter mit Readln und Eof.

Delphi-Quellcode:
unit StreamFile;
interface
Uses
  Classes, SysUtils;
 
Procedure AssignFile(Var f: Textfile; Stream: TStream);

implementation

function FileNOPProc(var t): Integer;
begin
  Result := 0;
end;

function TextStreamIn(var t: TTextRec): Integer;
Var
  S: TStream;
Begin
  t.BufEnd := 0;
  t.BufPos := 0;
  Move(t.UserData, S, SizeOf(TObject));
  t.BufEnd := S.Read(t.BufPtr^, t.BufSize);
  Result := 0;
End;

Function TextStreamOut(Var t: TTextRec): Integer;
Var
  S: TStream;
Begin
  Move(t.UserData, S, SizeOf(TObject));
  If S.Write(t.BufPtr^, t.BufPos) = t.BufPos Then
    Result := 0
  Else
    Result := 103;
  t.BufPos := 0;
End;

Function TextStreamOpen(Var t: TTextRec): Integer;
Var
  Mode: Integer;
Begin
  Mode := (fmInput and 3);
  Result := 0;
  t.BufPos := 0;
  t.BufEnd := 0;
  t.FlushFunc := @FileNOPProc;
  t.CloseFunc := @FileNOPProc;
  If Mode = (t.Mode and 3) then
  Begin
    t.InOutFunc := @TextStreamIn;
  End Else
  Begin
    t.InOutFunc := @TextStreamOut;
  End;
End;

Procedure AssignFile(Var f: Textfile; Stream: TStream);
Var
  t: TTextRec absolute f;
begin
  FillChar(t, sizeof(TFileRec), 0);
  t.BufPtr := @t.Buffer;
  t.Mode := fmClosed;
  t.Flags := tfCRLF * Byte(DefaultTextLineBreakStyle);
  t.BufSize := sizeof(t.Buffer);
  t.OpenFunc := @TextStreamOpen;
  Move(Stream, t.UserData, SizeOf(TObject));
  StrPCopy(t.Name, 'Stream');
end;        

end.

danieleh 27. Dez 2008 09:46

Re: Zeilen von einem Stream lesen
 
Hallo Andreas,
besten Dank für deinen Code.
Es ist mir allerdings nicht ganz klar wie man diesen einsetzt um bestimmte Zeilen aus dem Stream zu lesen. Ich schreibe und speichere ein Memo in ein Filestream. Danach möchte ich lediglich einzelne Zeilen daraus lesen (zb. Zeile 5).

Gruss
Daniele

Klaus01 27. Dez 2008 10:03

Re: Zeilen von einem Stream lesen
 
Guten Morgen Daniele,

was spricht dagegen, den Stream in eine StringList zu laden
und dort die gewünschte Zeile auszulesen.

Du mußt sowieso im worst case fast den ganzen Stream durchsuchen
um eine Zeile am Ende des Streams zu extrahieren.

Grüße
Klaus

alzaimar 27. Dez 2008 10:05

Re: Zeilen von einem Stream lesen
 
Random Access, also "wahlfreier Zugriff" ist ohne selbstgebaute Logik nicht möglich. Du musst die ersten 4 Zeilen auslesen, um dann die 5.Zeile zu bekommen. Das liegt daran, das die Zeilen unterschiedlich lang sind.

Du könntest Dir eine Methode basteln, die zur n.ten Zeile hüpft, indem Du nur die Längeninformation ausliest und anschließend die entsprechende Byteanzahl nach vorne wanderst (per 'Seek').

himitsu 27. Dez 2008 11:12

Re: Zeilen von einem Stream lesen
 
Wenn es nicht darauf ankommt die Xte Zeile zu lesen, sondern die Zeile an Position XYZ, dann könnte man auch einfach zu dieser Position springen, dann rückwärts den Zeilenanfang suchen und ab da diese Zeile auslesen.

danieleh 27. Dez 2008 15:08

Re: Zeilen von einem Stream lesen
 
Hallo Alle

Vielen Dank für Eure Beiträge. Es ist, wie ich befürchtet habe, nicht ganz trivial was ich vor hatte.
Deswegen ist der Ansatz von Klaus vielleicht doch der Beste in meinem Fall.

Liebe Grüße
Daniele


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