AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Records verwalten mit TList und TStream

Ein Thema von Panthrax · begonnen am 16. Jul 2005 · letzter Beitrag vom 16. Jul 2005
Antwort Antwort
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#1

Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 20:14
Salut.

Ich möchte mir ein Objekt zum Verwalten von Records, deren Quelle ein Stream ist, schaffen.

Im ersten Schritt habe ich mir die Klasse TList genommen und an sie die Information über die Recordgröße geknüpft. Fertig war meine Klasse TRecordList.

Im zweiten Schritt möchte ich erreichen, dass diese Liste ein TStream-Objekt als Standarddatenquelle nutzt. Mit der Eigenschaft Items[Index] soll dann auf jeden Record zugegriffen werden können. Ist der Record noch nicht im Speicher soll er aus dem Stream gelesen und in den Speicher kopiert werden. In jedem Fall gibt Items dann einen Pointer auf den Record im Speicher zurück. (Das vertraute Verhalten von TList.)

Dabei stellt sich mir folgendes Problem: Wie kann ich sicherstellen, dass die Records im Speicher gleich denen im Stream sind? Denn die Anwendung führt an anderer Stelle möglicherweise Schreib-Lese-Operationen an dem Stream durch.

Ich habe mir überlegt, wenn es dasselbe Objekt handhaben würde, bekäme es die Schreib-Lese-Operationen mit, und könnte geschriebene Records aus dem Speicher entfernen. (Besteht noch Lesebedarf werden sie ja erneut in den Speicher geholt.) Folglich brauche ich also ein Objekt, das TStream und TList zugleich ist. Das aber geht in Delphi nicht. Was kann ich tun? Hat jemand eine kozetionell andere Lösung? Ich bin für alles offen.

Noch ein Hinweis: Interfaces kommen nicht in Frage. Im Gesamtkontext gibt es zuviele Delphi-Routinen, die ich benutzen möchte, die TList- und TStream-Objekte erwarten.

Panthrax.

Hier noch etwas Quelltext zum Verständnis:
Delphi-Quellcode:
type
  { TRecordList
  Hier wird nur die Möglichkeit geschaffen, die Information über die Recordgröße bei der Liste zu hinterlegen. }

  TRecordList = class(TList)
    private
    FRecordSize: Integer;

    published
    property RecordSize: Integer read FRecordSize write FRecordSize;

    constructor Create(RecordSize: Integer);
  end;

constructor TRecordList.Create(RecordSize: Integer);
begin
  FRecordSize:=RecordSize;
end;

type
  { TRecordListStreamStreamBounded
  Diese Klasse ist nur eine Beispielimplementierung um zu demonstrieren, was die Eigenschaft Items tun soll, wenn ein Record nachgrfragt wird. }

  TRecordListStreamStreamBounded = class(TRecordList)
    private
    FBoundedStream: TStream;
    function GetItems(Index: Integer):Pointer;
    procedure SetItems(Index: Integer; const Value: Pointer);

    public
    property Items[Index: Integer]:Pointer read GetItems write SetItems; default;

    published
    constructor Create(BoundedStream: TStream);
    { Methoden die Records aus dem Speicher zu entfernen und zu speichern gibt es natürlich auch noch... }
  end;

constructor TRecordListStreamStreamBounded.Create(BoundedStream: TStream);
begin
  FBoundedStream:=BoundedStream;
end;

function TRecordListStreamStreamBounded.GetItems(Index: Integer): Pointer;
var
  RecordPtr: Pointer;
begin
  Result:=inherited Items[Index];
  if Result = NIL then with BoundedStream do
  begin
    GetMem(RecordPtr,RecordSize);
    try
      Seek(soFromBeginning,Index*RecordSize);
      Read(RecordPtr^,RecordSize);
        // Auf Read(...) <> RecordSize zu prüfen spar' ich mir jetzt mal.
    except
      FreeMem(RecordPtr,RecordSize);
    end;
  end;
end;

procedure TRecordListStreamStreamBounded.SetItems(Index: Integer;
  const Value: Pointer);
begin
  inherited Items[Index]:=Value;
end;
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 20:39
da komme ich auf folgende überlegungen:

man könnte daraus singletostream machen, welches

1. an die position des records springt, sprich alle werte der liste addiert, bis sie beim gesuchten record angekommen ist
2. den record schreibt
3. den record freigibt, seine größe aber hält

sowie singlefromstream, welches

1. an die richtige position springt
2. aus dem stream lädt
3. die größe in die liste einträgt

und wo liegt nun dein problem?
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#3

Re: Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 20:44
Du brauchst einfach nur die gleiche Instanz der Liste dort wo du die Liste verwendet hat und da wo du den Stream verwendest, ersetzen ihn gegen die Liste.
Erst beim Speichern/Lesen wird der Strream interessant. So klingt mir das nach zuviel Friemelei.
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#4

Re: Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 21:00
@DGL-Luke

Hm. - Ich hab' gerade ein geräzelt, was Du meinst, bin aber zu keiner Lösung gekommen. Bitte was ist SingleToStream und StreamToSingle?

Vielleicht noch einige Worte zum Hintergrund: Die Record-Dateien sind recht groß im Verhältnis zu den Recordgrößen. Wenn auf die Records zugegriffen wird, betrifft dies meist nur wenige. Mit dem vorhalten im Speicher wird also eine Art Caching angestrebt.

Und das Problem besteht darin, dass die Daten einmal als TStream-Objekt (mit all seinen Funktionen)und ein anderes Mal als TList-Objekt (mit all seinen Funktionen) betrachtet werden.

Es gibt Routinen die erwarten Parameter in dieser Weise:
Delphi-Quellcode:
procedure SaveToStream(Stream: TStream);
function EvalRecords(RecordList: TRecordList);
In beiden Fällen sind die zu verwaltenden Records als die Daten dahinter gefragt.

Panthrax.
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 21:10
die funktionen "singletostream" und "singlefromstream" sollst du selbst implementieren, und zwar, um einen einzelnen record zu süpeichern und einen einzelnen record zu laden - was ja offenabr dein ziel ist.

und wenn du meinen vorschlag nicht verstehst, dann kann ich dir vielleicht weiterhelfen, wenn du mir sagst, wie dein kenntnisstand bei streams ist.

@_G: häh? wir sind doch gerade beim speichern und laden, was erzählst du jetzt vom ersetzen?
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#6

Re: Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 21:21
Zitat von DGL-luke:
@_G: häh? wir sind doch gerade beim speichern und laden, was erzählst du jetzt vom ersetzen?
Ich glaube, dass er leiber den Teil der Liste, der für ihn interessant ist als das gleiche Object (Object== LIst, alles klar? ) überall verwendet. Somit wären Änderungen überall sichtbar.
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#7

Re: Records verwalten mit TList und TStream

  Alt 16. Jul 2005, 21:39
Mein Kenntnisstand bei Streams ist, dass ich gedenke TWinSocketStream zu überschreiben um von der Verbindung gelesene Streamdaten vorzuhalten, damit die Liste auf diesen Daten arbeiten kann. Werden Daten in über das Stream-Objekt Daten versendet, betrifft dies möglicherweise auch die Liste. Daher ist es wünschenswert die Stream-Funktionen und die Listen-Funktionen in einem Objekt zu vereinen. Oder eben, da dies in Delphi nicht geht, zwei sehr kooperative Objekte zu schaffen.

Zur Veranschaulichung:
Delphi-Quellcode:
{ eingehender Datenstrom }
+--------+--------+--------+--------+-------<
| Record | Record | Record | Record | ...
+--------+--------+--------+--------+-------<
     | { ausgehender Datenstrom }
     | +-------+----->
     | +-------+----->
     | A
     | |
+|||||||||||||||||||||||||||||||||||||||||||||||||||+
= | | =
= | Lesen (TWinSocketStream) | Schreiben =
= | | =
= V | =
= +===============================================+ =
= | TMyTWinSocketStream-Objekt | =
= +-----------------------------------------------+ =
= | { Hier gibt es einen Puffer. }                | =
= | { Der hält die Verbindungsdaten bereit, }     |<-----
= | { damit das TRecordListStreamBounded-Objekt } |----->
= | { sie anfordern kann. }                       | =
= +===============================================+ =
= | A =
= | Lesen (TMyWinSocketStream) | Schreiben =
= | | =
= V | =
= +===============================================+ =
= | TRecordListStreamBounded | =
= +-----------------------------------------------+<-----
= | { Verwaltung der Liste. }                     |----->
= +===============================================+ =
= =
+|||||||||||||||||||||||||||||||||||||||||||||||||||+
  Mit Zitat antworten Zitat
Antwort Antwort


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 14:26 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