![]() |
Delphi-Version: 10.2 Tokyo
Update/Delete Record items in a Stream
Hi every one , i save my records into a stream i can read them back , but what i want is to be able to update or delete one of my records item then save back .
please how to do that . thank you
Delphi-Quellcode:
Tmyrecord = Record
Firstname : string ; LastName:string; ID : integer ; end; .... procedure WriteIntegerToStream(Stream: TStream; Value: Integer); begin Stream.WriteBuffer(Value, Sizeof(Value)); end; procedure WriteStringToStream(Stream: TStream; const Value: String); var S: UTF8String; Len: Integer; begin S := UTF8String(Value); Len := Length(S); Stream.WriteBuffer(Len, Sizeof(Len)); Stream.WriteBuffer(PAnsiChar(S)^, Len); end; function ReadIntegerFromStream(Stream: TStream): Integer; begin Stream.ReadBuffer(Result, Sizeof(Result)); end; function ReadStringFromStream(Stream: TStream): String; var S: UTF8String; Len: Integer; begin Stream.ReadBuffer(Len, Sizeof(Len)); SetLength(S, Len); Stream.ReadBuffer(PAnsiChar(S)^, Len); Result := String(S); end; Procedure SaveToStream(); var SavingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try WriteStringToStream(SavingStream, myRec.Firstname); WriteStringToStream(SavingStream, myRec.LastName); WriteIntegerToStream(SavingStream, myRec.ID); finally SavingStream.Free; end; end; procedure LoadFromStream() var LoadingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin LoadingStream := TFileStream.Create('SAVE.test', fmOpenRead or fmShareDenyWrite); try myRec.Firstname:= ReadStringFromStream(LoadingStream); myRec.LastName := ReadStringFromStream(LoadingStream); myRec.ID := ReadIntegerFromStream(LoadingStream); finally LoadingStream.Free; end; end; procedure UpdateMyRecLastName(NewLastName:string); var LoadingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try myRec.LastName:=NewLastName; { Here how to update myRec.LastName value in the LoadingStream } finally SavingStream.Free; end; end; procedure DeleteMyRecLastName(); var LoadingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try { Here how to Delete myRec.LastName value in the LoadingStream } finally SavingStream.Free; end; end; |
AW: Update/Delete Record items in a Stream
Why not define a specialized list?
Delphi-Quellcode:
uses ..., System.Generics.Collections;
type TMyRecList = class(TList<Tmyrecord>) public procedure LoadFromFile(const Filename: string); procedure SaveToFile(const Filename: string); end; |
AW: Update/Delete Record items in a Stream
And then your next steps will probably be writing
Delphi-Quellcode:
or
UpdateFirstName
Delphi-Quellcode:
methods.
UpdateId
Why not
It looks like you already have everything you need. |
AW: Update/Delete Record items in a Stream
Zitat:
please read the
Delphi-Quellcode:
procedure UpdateMyRecLastName(NewLastName:string);
var LoadingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try myRec.LastName:=NewLastName; { Here how to update myRec.LastName value in the LoadingStream } finally SavingStream.Free; end; end; procedure DeleteMyRecLastName(); var LoadingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try { Here how to Delete myRec.LastName value in the LoadingStream } finally SavingStream.Free; end; end; |
AW: Update/Delete Record items in a Stream
Zitat:
|
AW: Update/Delete Record items in a Stream
what i wanted is to be able to :
1- Load that record item from Stream ( Done ) 2- Update that record item value ( Done ) 3- Update that modified record item value in the Stream , that means Replace that OLD item value with this New Value then save again ( HOW TO ) |
AW: Update/Delete Record items in a Stream
Can you post your real code? Your current
Delphi-Quellcode:
and
LoadFromStream()
Delphi-Quellcode:
appear to be testing routines because they contain syntax errors and, in their current form, do not make sense:
SaveToStream()
In
Delphi-Quellcode:
you load your data into a local variable
LoadFromStream()
Delphi-Quellcode:
. After that, your procedure ends and
myRec
Delphi-Quellcode:
is gone. You can inspect
myRec
Delphi-Quellcode:
in the debugger, but in the end, this method accomplishes nothing.
myRec
"Real code" would, for example, take an instance of
Delphi-Quellcode:
and a filename as parameters for
TMyrecord
Delphi-Quellcode:
and
LoadFromStream()
Delphi-Quellcode:
SaveToStream()
|
AW: Update/Delete Record items in a Stream
Zitat:
Delphi-Quellcode:
and
LoadFromStream()
Delphi-Quellcode:
, because i'll use my Rec else where , my issue now is with updating MyRec value then save it again ( at same stream position ) . thank you again
SaveToStream()
Delphi-Quellcode:
procedure UpdateMyRecLastName(NewLastName:string);
var LoadingStream: TFileStream; i, j: Integer; myRec:Tmyrecord; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try myRec.LastName := ReadStringFromStream(SavingStream); // load the OLD value myRec.LastName:=NewLastName; // update it { Here how to update myRec.LastName value in the LoadingStream } finally SavingStream.Free; end; end; |
AW: Update/Delete Record items in a Stream
I still don't understand the problem. Let's assume you change your local variable myRec to be a parameter of both LoadFromStream(..) and SaveToStream(..). They both now look like this:
Delphi-Quellcode:
If you want to change the LastName field of some file from disk, then all you need to do is
Procedure SaveToStream(const myRec:Tmyrecord);
var SavingStream: TFileStream; begin SavingStream := TFileStream.Create('SAVE.test', fmCreate or fmOpenWrite or fmShareDenyWrite); try WriteStringToStream(SavingStream, myRec.Firstname); WriteStringToStream(SavingStream, myRec.LastName); WriteIntegerToStream(SavingStream, myRec.ID); finally SavingStream.Free; end; end; procedure LoadFromStream(var myRec: TMyRecord); var LoadingStream: TFileStream; begin LoadingStream := TFileStream.Create('SAVE.test', fmOpenRead or fmShareDenyWrite); try myRec.Firstname:= ReadStringFromStream(LoadingStream); myRec.LastName := ReadStringFromStream(LoadingStream); myRec.ID := ReadIntegerFromStream(LoadingStream); finally LoadingStream.Free; end; end;
Delphi-Quellcode:
The old file ("save.test") will get overwritten and the file will only contain the data stored in
var
myRec: Tmyrecord; begin LoadFromStream(myRec); myRec.LastName := 'Wombat'; SaveToStream(myRec); end;
Delphi-Quellcode:
.
myRec
|
AW: Update/Delete Record items in a Stream
many thanks for your great efforts , is there any other alternative to load just one field say :
Delphi-Quellcode:
let's update
myRec.LastName := ReadStringFromStream(LoadingStream);
Delphi-Quellcode:
with a new value
myRec.LastName
Delphi-Quellcode:
// to change
myRec.LastName := 'Wombat';
not the whole record then save only this new field value , something like update then save whithout loading the whole record just the target one . I hope you get me now . like this step : ![]() please read the "Change and Update" part |
AW: Update/Delete Record items in a Stream
I do get you, and I understand what you want. It's just my personal opinion: I believe there is absolutely no use of putting this much work into all of this when everything you need is already there. It makes no sense to not read and write a few bytes.
Anyway :), the part above ("Seeking and Positioning") is important as well. When you only want to read the LastName part of your file, you will have to skip the
Delphi-Quellcode:
part. Since you do not know how many bytes are used to store the FirstName, you will first have to read the length of FirstName, then use
FirstName
![]() I'll give you two examples: The easiest one first:
Delphi-Quellcode:
function loadLastNameFromStream_EASY(): String;
var LoadingStream: TFileStream; begin LoadingStream := TFileStream.Create('SAVE.test', fmOpenRead or fmShareDenyWrite); try // read it, but do nothing with it ReadStringFromStream(LoadingStream); Result := ReadStringFromStream(LoadingStream); finally LoadingStream.Destroy(); end; end; The harder part is essentially the same. The "advantage" is not reading the UTF8 text bytes of
Delphi-Quellcode:
. The disadvantage is that you end up more complicated code:
FirstName
Delphi-Quellcode:
function loadLastNameFromStream_HARDER(): String;
var LoadingStream: TFileStream; stringLength: Integer; begin LoadingStream := TFileStream.Create('SAVE.test', fmOpenRead or fmShareDenyWrite); try // determine length of FirstName LoadingStream.ReadBuffer(stringLength, SizeOf(stringLength)); // skip LoadingStream.Seek(stringLength, TSeekOrigin.soCurrent); // we have now reached the position where "LastName" is stored, proceed as usual Result := ReadStringFromStream(LoadingStream); finally LoadingStream.Destroy(); end; end; Once again: I believe you're taking the wrong approach. We have now a way of just reading the "LastName" part from a file. The way of writing the LastName is much more complicated: You can't just put a few additional bytes into a file and keep the rest as it is. When you change the LastName to something longer, you will also overwrite the ID part in your file. If you change the name to something shorter, garbage data will remain between the end of
Delphi-Quellcode:
and
LastName
Delphi-Quellcode:
.
ID
To avoid corruption, you will first have to read everything that comes after LastName, then seek back to where LastName starts, then write your LastName part, and then write everything else you previously read in. Then, in case your new name is shorter, truncate the file so no garbage data remains at the end. Is all of this worth the hassle? No, it's not. You have a handy method of reading a TMyRecord, and writing one as well. Just use them and use all the time saved for something nice. :wink: |
AW: Update/Delete Record items in a Stream
So many thanks for all your great efforts .
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:38 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