![]() |
Pointer :\
hi,
eigentlich dürfte das thema kein problem sein aber wieso kann ich den pointer so nicht benutzen ?? ich weiss der code macht so keinen sinn aber ich wollte nicht den kompletten code posten, zumal der Fehler bei fi := fp^; auftritt Fehlermeldung : Operator auf diesen Operatortyp nicht anwendbar
Code:
var
fi : File; fp : ^File; begin fp := @fi; fi := fp^; .. end; |
Re: Porinter :\
Zitat:
Meines Wissens kann man keine Pointer auf <File> setzen. Möchtest Du mit "fi := fp^;" an den Inhalt von der Datei rankommen oder wie? :gruebel: Mir ist momentan noch nicht ganz klar, was Du machen möchtest, aber für Dateiverarbeitung sollest Du evtl. ![]() verwenden. Was genau möchtest Du denn tun? :gruebel: Wenn Du uns das verrätst, können wir Dir hoffentlich weiterhelfen. DANNBOY Nachtrag: Nenn' Deine Überschrift besser "Pointer". Ist aussagekräftiger als "Porinter". :zwinker: |
Re: Pointer :\
Prointer .. lol gar net gesehen
ich schreibe eine kompone die daten in eine datei typweise speichert daher benutze ich in der gasamten komponente die selbe variable vom typ file daich beim übergeben nicht immer die gesamte variable übergeben möchte wollte ich einen pointer stattdessen übergeben .. aber wenn das nicht geht :\ schade |
Re: Pointer :\
Zitat:
Wie wäre es denn, wenn Du einen Zeiger auf die Variable (nicht auf die Datei) an einen FileStream übergibst? :gruebel: Bei der write-Funktion von TFilestream kannst Du ebenso exakt die Anzahl der zu schreibenden Bytes (die Quelle wäre dann der Pointer Deiner Variable) angeben. Ich beschäftige mich z.Zt. auch mit dem Erstellen einer Datei, in die verschiedene Variablen mit unterschiedlichen Längen und unterschiedlichen Datentypen rein kommen. Klappt mit Filestreams ganz easy. |
Re: Pointer :\
*g
mh ich hab nu soweit alles mit assign ..reset .. rewrite usw. gemacht gibts denn einen direkten vorteil gegenüber filestream ? |
Re: Pointer :\
Liste der Anhänge anzeigen (Anzahl: 1)
Dieses ganze AssignFile-reset-rewrite-closeFile-Zeugs stammt
noch aus der Pascal-Zeit. Ich hab's damals auch so gelernt und hatte kein Bock umzusteigen, aber das mit den Filestreams ist wirklich (!) ganz einfach und bietet viele Vorteile der Einfachheit und vor allem in der Geschwindigkeit. Wenn Du z.B. einen Dateisplitter für beliebige Dateien schreiben möchtest (siehe Anhang) dann kennst Du die Struktur der Dateien meistens gar nicht. FileStreams sehen Strukturen einfach als eine Menge von einzelnen Bytes an. Möchtest Du z.B einen Record speichern, dann machst Du das so:
Delphi-Quellcode:
Vorteile von der Pascal-Variante sind mir nicht bekannt. Hab' das aus dem
type TMeinRecord = record
buchstabe : Char; alter : byte; groesse : real; Daten : array[0..7] of byte; end; //... var MeinRecord : TMeinRecord; //... procedure schreibeMeinRecordInDatei; var Filestream: TFileStream; begin // FileStream:= TFileStream.create(<Dateiname>, <Zugriff auf Datei>); FileStream:= TFileStream.create('C:\test.dat', fmCreate OR fmShareExclusive); // FileStream.write(<dantenquelle>, <anzahl der bytes>) FilStream.write(MeinRecord, SizeOf(TMeinRecord); // Dateizugriff freigeben FileStream.free; end; Kopf geschrieben, ergo ungetestet. Nachtrag: Musst natürlich noch eventuelle Exceptions abfangen. |
Re: Pointer :\
Zitat:
Nur, was hat das ganze mit Dateien zu tun ? Wahrscheinlich weißt du nicht, wieviel Platz irgendwas zur Laufzeit braucht. Und das soll in eine Datei. Wenn dem so ist, dann willst du das wohl in einer typisierten Datei speichern und das ist auch richtig. Wer weiß beim Programmieren schon, ob eine Rechnung jetzt 1 oder 1000 Positionen hat. Was du wohl mit "Pointer" meinst, das sind dynamische Datenstrukturen (Listen, Bäume usw.). Da spielt sich aber alles im Hauptspeicher ab. Soll es längere Zeit gespeichert bleiben, so gehört es in eine Datei / Datenbank. Das alles ist aber auch dynamisch. So, jetzt bin ich mit meinem Latein am Ende, was das ganze soll. :gruebel: |
Re: Pointer :\
Zitat:
ich wollte einfach statt der variablen File einen pointer übergeben aber so langsam glaub ich, dass das etwas blöd war :gruebel: @Dannyboy könnte ich damit auch listen ( arrays ) speichern, sieht bei deinem bsp so aus, wenn dem das so wäre würde ich sofort darauf umsteigen; gleich mal testen :mrgreen: |
Re: Pointer :\
mh, damit kann man leider keine dynamischen listen speichern,
schade .. naja hätte ich mir auch denken können .. egal dennoch danke euch :) |
Re: Pointer :\
Zitat:
Delphi-Quellcode:
type TArray = array[0..1000, 3..99999] of integer;
Var meinArray : TArray; //... Filestream.write(meinArray, SizeOf(meinArray)); //... Zitat:
Du muss nur an den Eintrag der Liste rankommen und dann wie gehabt:
Delphi-Quellcode:
Check this out.
VAR Eintrag : TListEintrag;
//... FileStream.write(Eintag, SizeOf(Eintrag)); //... DANNYBOY |
Re: Pointer :\
Wie man an Dannyboys Beispiel schön sieht : er hat soviel Speicher reserviert, wie er maximal glaubt zu brauchen. Verschätzt er sich so hat er Pech. Ist der Platz zu gering bemessen dann auch.
Jetzt kommen Dateien und Listen ins Spiel. Letzteres ist wohl das, was du unter deinen "Porintern" verstehst. :mrgreen: Das betrifft aber nur den Hauptspeicher. Geht also nur, während das Programm läuft. Soll es gespeichert werden, na dann sind Dateien vorzuziehen. |
Re: Pointer :\
Zitat:
In meinem Beispiel wollte ich illustrieren, dass man ein großes, statisches Array in eine Datei schreiben kann. Das hat gar nichts mit verschätzen zu tun, da hier gar nix berechnet werden muss und es ging in meinem Beispiel auch gar nicht um irgend was dynamisches. Es ist einfach nur ein großes, gefülltes, statisches Array, das in eine Datei geschoben wird. Da ich die Datenstrukturen von Snoop007 nicht kenne, habe ich exemplarisch (er hatte bisher noch nichts mit Filestreams gemacht) einfach mal die Größe des kompletten Arrays (bzw. Records) übergeben. Ich kann bisher noch nicht erkennen, in wiefern ein solcher Stream einem dynamischen Element (lineare Liste, binärer Baum, etc.) im Wege stehen sollte. Du, Hansa, schreibst von der Verwaltung von Speicher und ich schreibe von Streams. ... Das eine hat mit dem anderen erst mal nix zu tun, bis zu dem Zeitpunkt, in dem die Daten in eine Datei transportiert werden. Ich sehe kein Problem darin, einzelne Einträge einer dynamischen Liste in einen Stream zu packen und in Datei zu speichern. Wo hakt's denn? :gruebel: |
Re: Pointer :\
Zitat:
|
Re: Pointer :\
Wir hatten damals im Informatik-Untericht die ganzen Listen und Bäume selbst mit
Zeigern schreiben dürfen (Pascal 7). In Delphi gibt's ja bestimmt vordefinierte Konstrukte dafür, so dass man sich den Stress sparen kann. |
Re: Pointer :\
Moin,
alle die mit streams dynamische formate schreiben und laden wollen kann ich nur die TFiler klassen (TReader und TWriter) ans herz legen. Die sind wirklich sehr leicht in der handhabung und bieten für alle gängigen stadardtypen entsprechende funktion. Somit muss man sich nicht mehr mit buffern und der länge der daten herrum schlagen und kann sehr schön sequenziell lesen und schreiben. Hier ein beispiel zum streamen einer 2D map:
Delphi-Quellcode:
Nur so als anregung, da ihr grad über dynamische (oder auch nicht) formate redet. Was meint ihr?
Function TMap.SaveToStream(stream: TStream):Boolean;
Var writer : TWriter; i : integer; begin result := true; writer := TWriter.Create(stream, $ff); try try writer.WriteSignature; writer.WriteListBegin; writer.WriteString(ClassName); WriteData(writer); writer.WriteListEnd; except result := false end; finally writer.Free; end; end; Function TMap.LoadFromStream(stream: TStream):Boolean; Var reader : TReader; ctype : TPersistentClass; cname : string; begin result := true; reader:=TReader.Create(stream,$FFFF); try with reader do begin {read at beginning of file} ReadSignature; ReadListBegin; cname := ReadString; ctype := GetClass(cname); if Assigned(ctype) then begin try ReadData(reader); except result := False; end; end; ReadListEnd; end; finally reader.Free; end; end; procedure TMap.ReadData(reader: TReader); var x,y,size : integer; begin size := sizeOf(TField); with reader do begin MapName := ReadString; coment := ReadString; Bounds.X := ReadInteger; Bounds.Y := ReadInteger; //-- Read matrix ----- SetToBounds(bounds,false); for x := 0 to Bounds.X-1 do for y := 0 to Bounds.Y-1 do Read(matrix[x,y],size); //---------------------- ReadString; style := Readinteger; mode := Readinteger; TimeLimit := Readinteger; GUID := ReadString; Creator := ReadString; CreateDate := ReadDate; end; end; procedure TMap.WriteData(writer: TWriter); var x,y,size : integer; begin size := sizeOf(TField); with writer do begin WriteString(MapName); WriteString(coment); WriteInteger(Bounds.X); WriteInteger(Bounds.Y); //-- Write matrix ----- for x := 0 to Bounds.X-1 do for y := 0 to Bounds.Y-1 do Write(matrix[x,y],size); //---------------------- WriteString(''); Writeinteger(style); Writeinteger(mode); Writeinteger(TimeLimit); WriteString(GUID); WriteString(Creator); WriteDate(CreateDate); end; end; |
Re: Pointer :\
:gruebel: ihr machts einem auch nicht leicht ^^
das mit den pointern habe ich es so gemeint wie ich esgeschrieben hatte, ich kenne den unterschied, *g vielleicht hab ich mich auch falsch ausgedrückt, oder ich habe versucht was unmögliches zu machen, wie es aus sah, also nochmal kurz dazu ich wollte statt den wert der variabeln vom typ File, einfach einen pointer, der auf diese variable zeigt, übergeben und mit diesem pointer weiter hantieren, scheint aber nicht zu gehen ok, abgehkt :) zu filestream, die liste sollte schon dynamisch sein, da ich nicht so viel speicher reservieren möchte, die komponente beinhaltet mehrere dynamische attribute ich frage mich nur, ob man mit filestream auch dynamische listen recht einfach speichern kann, recht einfach soll hier heissen, ich gebe einfach nur den typ / das 1. element des array(liste) an anstatt das gesamte array (liste) zu druchlaufen und jeweils den wert speichern dass das mit typen ( records die ein "ende" haben ) geht, ist klar |
Re: Pointer :\
Was du machen willst hört sich wirklich nach der Quadratur des Kreises an. Ich habe so was schon befürchtet. 8)
Also nochmals : was soll gespeichert werden ? Ist die Gesamtgröße stark variabel, oder die einzelnen Elemente ? Sogar in letzterem Fall gibt es noch eine Variante. Nämlich variante Records. Verstehe sowieso nicht ganz, warum du das mit Pointern machen willst. Normalerweise will sich jeder davor drücken. Meist wird nach Auswegen gesucht, um da drumrum zu kommen. :mrgreen: |
Re: Pointer :\
Wenn Dein dynamische Array ausschliesslich Nicht-Zeiger-Typen (keine Strings, Objekte) beinhaltet und auch nur eindimensional ist, kannst Du es mit einer SizeOf*Length-Konstruktion wie beim statischen Array an einen Stream übergeben.
In allen anderen Fällen musst du jeden einzelnen Wert durchlaufen. Gruß, teebee |
Re: Pointer :\
hehe, die komponente sollte so schnell wie möglich daten verarbeiten können
die komponente ist eine klasse, die 2 records beinhaltet, diese 2 records haben ca. 2 - 3 records und paar dynamische listen die records der records haben dynamische elemente so und da ich nun alle durcheinander gebracht habe sell ich das mal grafisch dar :mrgreen:
Code:
gespeichert werden soll die hauptkomponente
Hauptkomponente ( class )
| --record | | | |- record | |- record | |- attribute | |- attribute [] ( länge dynamisch ) | | - record | |- attribute | |- attribute [] ( länge dynamisch ) | |--record |- record |- attribute |- attribute [] ( länge dynamisch ) |- attribute [] ( länge dynamisch ) ich wollte schon anfangen die listen zu druchlaufen und jedes elemt der liste einzeln zu speichern, wäre ja schönn wenn das mit erspart bliebe :mrgreen: aber ich glaube das geht nicht edit : doch, die array bestehen meist aus strings allerding mit "nur" 254 zeichen |
Re: Pointer :\
Ein wichtiges weiteres Problem ist übrigens bei dynamischen Längen das Einlesen: Du musst wissen, von wo bis wo Do einlesen musst, also muss die Länge eines Blocks irgendwo stehen. Ich denke, um eine eigene Speicherlogik wirst Du nicht herumkommen.
Gruß, teebee |
Re: Pointer :\
@Snoop007: hast du mein posting von der letzten seite gesehen? Mit den Filer-klassen sind solche strukturen kein problem -> siehe WriteBegin, WriteListEnd etc. - Schliesslich wurde diese klassen designed um die delphi komponenten-bäume zu speichern (binär wohlgemerkt). Man kann sie aber auch für alle anderen zwecke einsetzen!
|
Re: Pointer :\
@TeeBee, die struktur der datei und das ganze geplante ist abgeschlossen und wird nun in die tat umgesetzt
@maximov, ich seh bei deinem code keine klasse, keinen record, dein dynamisches element :gruebel: vielleicht bin ich auch nur bissel doof :stupid: |
Re: Pointer :\
Das array (matrix) ist ein dynamisches array of record und die strings sind auch alle dynamisch und die klassen sind TFiler und TReader (classes.pas). Sieht man doch. Die ganzen deklarationen hab ich weggelassen, weil ich nur den umgang mit den filer-klassen demonstrieren wollte!
|
Re: Pointer :\
aber so kann ich da nichts erkennen, da ich ja nicht weiss, wie das ganze zusammenhängt
wäre nett, wenn du das evtl. als anhang dran hängen könntest :) |
Re: Pointer :\
Na, ok:
Delphi-Quellcode:
Die bezeichner der felder und properties sind nicht sehr stardardmässig da der code schon sehr alt ist, aber einer meiner ersten schönen dynamischen streaming-versuche :wink:
Type
TField = record way : byte; item : byte; tag : byte; flags : byte; ran : byte; end; TMatrix = array of array of TField; TMap = class(TDynaVisible) Private FMapFile: string; procedure SetMapFile(const Value: string); Public MapName : STring; Coment : String; Bounds : TPoint; Matrix : TMatrix; style : integer; mode : integer; TimeLimit : integer; GUID : STring; Creator : String; CreateDate : TDateTime; Function SetToBounds(xBounds: TPoint; NoKill: boolean = true):TPoint; procedure ReadData(reader : TReader); dynamic; procedure WriteData(writer : TWriter); dynamic; Function SaveToStream(stream : TStream):Boolean; Function LoadFromStream(stream : TStream):Boolean; Function LoadFromeFile(const fName: String):Boolean; Function SaveToFile(const fName: String):Boolean; published property iName : string read MapName; property iComent: string read Coment; property iStyle: integer read style; property iMode: integer read Mode; property iTimeLimit: integer read TimeLimit; end; ... function TMap.SetToBounds(xBounds: TPoint; NoKill: boolean = true): TPoint; // setzt die dynamische grössen des map-arrays. function TMap.LoadFromeFile(const fName: String): Boolean; var stream : TFileStream; begin stream := TFileStream.Create(fname, fmOpenRead); try LoadFromStream(stream); finally stream.Free; end; end; function TMap.SaveToFile(const fName: String): Boolean; var stream : TFileStream; begin stream := TFileStream.Create(fname, fmCreate or fmOpenWrite); try SaveToStream(stream); finally stream.Free; end; end; |
Re: Pointer :\
ah super danke :) :thumb:
woher wusstest du das, es TWrite gibt bzw. was es macht ? aus einem tut oder Buch ? an alle anderen vielen dank ! |
Re: Pointer :\
Habs durch zufall gefunden und war begeistert :-D Leider war es damals undokumentiert und die tuts sehr mager. Die filer sind halt coole stream-helper und ganz einfach, wenn man einmal begriffen hat wie sie arbeiten.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 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