Entwickler-Ecke
Dateizugriff - TFielStream.seek aber wie ?
mimi - So 03.08.03 12:02
Titel: TFielStream.seek aber wie ?
Hallo,
ich möchte eine bestimen datensatzt auslesen.
schreiben tue ich so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64:
| procedure TMfa.Packe; var Datei:TStream; i,len,Size:Integer; DateiHeader:String; Test:TSearchRec; CFTime, EFTime, RFTime:_FileTime;
begin Datei := TFileStream.Create(FileName, fmCreate);
Len:=Dateien.Count; Datei.Write(Len, SizeOf(Len)); for i:=0 to Dateien.Count-1 do begin FindFirst(Dateien.Strings[i], faAnyFile,test); FileTimeToLocalFileTime(test.FindData.ftCreationTime, CFTime); FileTimeToLocalFileTime(test.FindData.ftLastWriteTime, EFTime); FileTimeToLocalFileTime(test.FindData.ftLastAccessTime, RFTime);
DateiHeader:=Dateien.Strings[i] + ';' + DateTimeToStr(FileTimeToDateTime(CFTime)) + ';' + DateTimeToStr(FileTimeToDateTime(EFtime)) + ';' + DateTimeToStr(FileTimeToDateTime(RFtime)) + ';' + IntToSTr(test.Size) + ';' + FileGetTypeName(Dateien.Strings[i]) + ';' + 'PositionA' + ';' + 'PositionE'; Len:=StrLen(PChar(DateiHeader)); Datei.Write(Len, SizeOf(Len)); Datei.Write(PChar(DateiHeader)^,Len); DateiHeader:=''; end; Datei.Free; end;
procedure TMFa.Entpacke(Index:Integer); var Datei:TStream; len:Integer; DateiHeader:String; begin Datei := TFileStream.Create(FileName, fmOpenRead); Datei.Read(Len, SizeOf(Len)); SetLength(DateiInfo,len); Datei.Seek(Datei.Position+index+1,soFromBeginning);
Datei.Read(Len, SizeOf(Len)); SetLength(DateiHeader,Len); Datei.Read(PChar(DateiHeader)^, Len); ShowMessage(DateiHeader);
Datei.Free; end; |
allerdinks gibt es ein fehlermeldung "zu wenig arbeitspeicher"
kann mir jemmand sagen wie ich mit seek arbeiten muss damit es funktioniert ???
AndyB - So 03.08.03 12:07
Dein Einlese Konzept passt nicht zur Schreibfunktion. Zudem hast du ein Speicherleck, da du den mit FindFirst reservierten Speicher nicht mit FindClose wieder frei gibst.
mimi - So 03.08.03 12:17
habe ich der schreib funktion hinzugefügt.
und warum geht das lesen nicht so wie ich es haben wollte ?
wenn ich alles per forschleife auslese geht es prima nun wollte ich gerne nur einen bestiemmten eintrag auslesen, aber wie geht das ?
Tryer - So 03.08.03 12:29
Das lesen funktioniert nicht weil Du versuchst direkt an eine Stelle zu springen die Du garnicht genau kennst.
Um das Element mit dem Index zu erreichen must Du halt immer wieder die Länge des nächsten Eintrags auslesen und dann um diese Länge weiterspringen. Dann wieder auslesen usw. bis Du "Index"-mal gesprungen bist.
MfG,
Tryer
mimi - So 03.08.03 14:04
ich habe es jetzt so versucht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75:
| procedure TMfa.Packe; var Datei:TStream; i,len,Size:Integer; DateiHeader:String; Test:TSearchRec; CFTime, EFTime, RFTime:_FileTime; DL:String; begin Datei := TFileStream.Create(FileName, fmCreate); Datei.seek(100,soFromBeginning); Len:=Dateien.Count; Datei.Write(Len, SizeOf(Len));
for i:=0 to Dateien.Count-1 do begin FindFirst(Dateien.Strings[i], faAnyFile,test); FileTimeToLocalFileTime(test.FindData.ftCreationTime, CFTime); FileTimeToLocalFileTime(test.FindData.ftLastWriteTime, EFTime); FileTimeToLocalFileTime(test.FindData.ftLastAccessTime, RFTime);
DateiHeader:=Dateien.Strings[i] + ';' + DateTimeToStr(FileTimeToDateTime(CFTime)) + ';' + DateTimeToStr(FileTimeToDateTime(EFtime)) + ';' + DateTimeToStr(FileTimeToDateTime(RFtime)) + ';' + IntToSTr(test.Size) + ';' + FileGetTypeName(Dateien.Strings[i]) + ';' + 'PositionA' + ';' + 'PositionE'; Len:=StrLen(PChar(DateiHeader)); dl:=dl + IntTostr(Datei.Position) + ',' + InttoStr(Len) + '|' ; Datei.Write(Len, SizeOf(Len)); Datei.Write(PChar(DateiHeader)^,Len);
DateiHeader:=''; end; len:=StrLen(PChar(DL)); Datei.seek(0,soFromBeginning); Len:=StrLen(PChar(DL)); Datei.Write(Len, SizeOf(Len)); Datei.Write(PChar(dl)^, len);
Datei.Free; FindClose(test); end;
procedure TMFa.Entpacke(Index:Integer); var Datei:TStream; len:Integer; DateiHeader:String; DL:String; begin Datei := TFileStream.Create(FileName, fmOpenRead);
Datei.Read(Len, SizeOf(Len)); SetLength(DL,len); Datei.Read(PChar(DL)^, Len); Datei.seek(100,soFromBeginning); Datei.Read(Len, SizeOf(Len)); SetLength(DateiInfo,len); Datei.seek(StrToInt(GetToken(GetToken(DL,'|', index),',',1)),soFromBeginning);
len:=StrToInt(GetToken(GetToken(DL,'|', index),',',2)); SetLength(DateiHeader,Len); Datei.Read(PChar(DateiHeader)^, Len); ShowMessage(DateiHeader);
Datei.Free; end; |
jetzt mache ich das so:
an pos 0 werden die größen und die länge abgespeichert von den einzelnen datenstätzen.
und beim auslesen soll dahin gegangen werden.
Aber das geht auch nicht :(
kann mir wer sagen wie ich das richtig machen könnte ?
das format soll jetzt nämlich so aussehen:
Anfangposition,größe| und soweiter
anzahl der dantenstäze(4)
Dateiname + ';' + .......
aber irgenwie klappt das nicht so wie ich es haben will :(
habe auch erst gestern mit tfilestream angefangen.
Tryer - So 03.08.03 15:19
Wie wär´s mal mit nem einfachen
Tutorial [
http://www.tutorials.delphi-source.de/streams/] ?
Mit einer Indexliste am Anfang machst Du es Dir nur noch schwerer, so wird das nichts.
Tip für später: Statt n Byte auszulesen kann man auch n Byte ab der aktuellen Position weiterspringen, man erreicht immer die gleiche Position.
Wenn man das mit einer bestimmten Häufigkeit machen will muss man halt mitzählen.
MfG,
Tryer
mimi - So 03.08.03 15:24
diese tutor kenne ich schon, das war die basis für die idee.......
das prinzip habe ich ja verstanden nur was noch fehlt sind die idee wie ich es am besten umsetzten könnte, das ziel soll es sein:
das man ein header hat aus den man nun bestimmte zeilen auslesen kann und mehr will ich ja eingetnlich garnicht, dachte nicht das es so schwer wird das umzusetzen.
Tryer - So 03.08.03 15:33
Dann fang mit der einfacheren Variante an:
Lies vom Prinzip erstmal alles aus was Du vorher auch reingeschrieben hast.
Dabei liest Du dann halt nicht bis "Dateien.Count" sondern nur bis "Index".
Spätere Optimierungen sind dann immer noch möglich.
MfG,
Tryer
mimi - So 03.08.03 19:18
wie meinst du das ?
komme irgendwie nicht gans mit :(
Tryer - So 03.08.03 19:30
Das simpelste wäre wohl wenn Du das Tutorial erstmal vollständig durcharbeitest, ohne am Algorithmus was zu ändern.
Wenn Du es dann
verstanden hast (nicht blos abgetippt), dann kannst Du Dich an schwierigere Probleme heranwagen.
Nimm Also z.B. eine Listbox und lege die inhalte in einem eigenen Stream ab um sie dann wieder zu laden, ohne auf LoadfromStream / SaveToStream zurückzugreifen.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Speichern: - Anzahl der Elemente in den Stream schreiben - von 0 bis Anzahl - 1: - Länge des Strings in den Stream schreiben - String in den Stream, schreiben
Laden: - Anzahl der Elemente auslesen - von 0 bis Anzahl - 1: - Länge des Strings auslesen - String auslesen - String in die Listbox eintragen |
MfG,
Tryer
mimi - So 03.08.03 19:36
ich habe ja das prinzip verstanden und das tutor auch durchgearbeitet.
und load.... und save... nutze ich auch garnicht davonmal abgesehen:)
naja mal sehen ob ich es noch schaffe:)
mimi - Do 07.08.03 14:50
hat sich erledigt, habe es hinbekommen:)
muss jetzt nur noch den datei inhalt hintendran packen und fertig, dafür überlege ich mir z.Z. noch ein brauchbare funktion.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!