Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.01.16;
Скачать: CL | DM;

Вниз

Сохранение/чтение Объектов TStringLista   Найти похожие ветки 

 
Каспер ©   (2002-12-26 08:32) [0]

Народ есть TStringList
Как сохранить список + все его объекты.
Спасибо и с начтупающим!


 
Song ©   (2002-12-26 08:38) [1]

А что такое "все его объекты"?


 
Каспер ©   (2002-12-26 09:02) [2]

Строка1 - имеет объект строку длшиной Х
Строка2 - имеет объект строку длшиной а
Строка3 - имеет объект строку длшиной й
Строка4 - имеет объект строку длшиной ц
Строка5 - имеет объект строку длшиной у
Строка6 - имеет объект строку длшиной я


 
gek ©   (2002-12-26 09:04) [3]

Посм на название TStringList - список строк
savetofile
Объекты хранить тоже можно


 
Юрий Зотов ©   (2002-12-26 09:16) [4]

> Каспер

Обычно под словом "объект" понимается адрес. Сохранить адрес можно, как обычное целое число. Но в этом нет никакого смысла, поскольку при следующем запуске программы эти адреса окажутся недействительными.

Если же под словом "объект" Вы понимаете не адрес, а сами данные, то сохранить нет проблем. Напишите наследник класса, в нем перекройте метод DefineProperties, а к нему напишите методы Read/Write. Примеры есть в VCL.


 
Каспер ©   (2002-12-26 10:21) [5]

Спасибо всем!
Действенный совет был от известного дои Юрия.
Разумеется я понимал не адрес а сами данные (сори за неточность)
Еще раз спасибо! Счастливого нового года :)


 
Каспер ©   (2002-12-26 10:26) [6]

Сорри .. хотел сказаьт ДОКИ.. :)


 
Каспер ©   (2002-12-26 10:57) [7]

Не особо там понятно в исхониках :(
Может есть где примеры для чайников.
Буду рад и представленным здесь примерам и ссылкам...
Опыт работ с отоками небольшой...


 
Skier ©   (2002-12-26 11:18) [8]

Посмотри, например, это :
ObjectBinaryToText и ObjectTextToBinary


 
Каспер ©   (2002-12-26 14:11) [9]

Млин люди :(
Высношал весь мозг...
Есть у кого нить примеры
Плиз не материте токо.
1 Список из строк ...
2 к каждой строке привязан
MyRec =record
x,y,integer;
LenS:integer; {длина нижеприведенной S}
S:string; {длина разная указана в переменной выше}
end;
Как все это сохранить в файл...
Если кто сможет найти пример как предложил Юрий Зотов вообще цены не будет, но буду рад любому примеру...
Накидайте плиз все кто что может...
Спасибо


 
Каспер ©   (2002-12-26 14:31) [10]

Можно по асе - 70015922 только киньте сразу что по поводу Дельфей...


 
Skier ©   (2002-12-26 14:42) [11]

>Каспер
1) И где же ты увидел здесь объекты ?!
2) Посмотри как сделаны методы WriteInteger и WriteString
в классе TWriter, должно помочь...


 
gek ©   (2002-12-26 15:11) [12]

тут в принципе можно файл записей сделать и читать все оттуда


 
Skier ©   (2002-12-26 15:54) [13]

Примерно так :

TMyObj = class
private
x,y : integer;
S:string;
end;

//.........................

procedure TForm1.Button3Click(Sender: TObject);

procedure SaveStrListToFile(AList : TStringList;
const AFileName : String);
var
ii : Integer;
AFileStream : TFileStream;
ALength : Integer;
ACount : Integer;
begin
if (AList = nil) or
(AFileName = EmptyStr) then Exit;
AFileStream := TFileStream.Create(AFileName, fmCreate);
try
ACount := AList.Count;
AFileStream.Write(ACount, SizeOf(Integer));
for ii := 0 to AList.Count - 1 do begin
with TMyObj(AList.Objects[ii]) do begin
AFileStream.Write(x, SizeOf(Integer));
AFileStream.Write(y, SizeOf(Integer));
ALength := Length(S);
AFileStream.Write(ALength, SizeOf(Integer));
AFileStream.Write(Pointer(S)^, ALength);
end; //with
end; //for
finally
FreeAndNil(AFileStream);
end;//try
end; //SaveStrListToFile

procedure LoadStrListFromFile(AList : TStringList;
const AFileName : String);
var
ii : Integer;
AFileStream : TFileStream;
ALength : Integer;
ACount : Integer;
AMyObj : TMyObj;
begin
if (AList = nil) or
(AFileName = EmptyStr) then Exit;
AFileStream := TFileStream.Create(AFileName, fmOpenRead);
try
AFileStream.Read(ACount, SizeOf(Integer));
for ii := 1 to ACount do begin
AMyObj := TMyObj.Create;
AFileStream.Read(AMyObj.x, SizeOf(Integer));
AFileStream.Read(AMyObj.y, SizeOf(Integer));
AFileStream.Read(ALength, SizeOf(Integer));
SetString(AMyObj.S, PChar(nil), ALength);
AFileStream.Read(Pointer(AMyObj.S)^, ALength);
AList.AddObject(AMyObj.S, AMyObj);
end; //for
finally
FreeAndNil(AFileStream);
end;//try
end; //LoadStrListFromFile

var
AList : TStringList;
AMyObj : TMyObj;
ii : Integer;
begin
AList := TStringList.Create;
try
for ii := 1 to 10 do begin
AMyObj := TMyObj.Create;
AMyObj.x := 10;
AMyObj.y := 100;
AMyObj.s := "Hello N = " + IntToStr(ii);
AList.AddObject(AMyObj.s, AMyObj);
end; //for
SaveStrListToFile(AList, "C:\###\111.dat");
for ii := 1 to 10 do AList.Objects[ii - 1].Free;
AList.Clear;
LoadStrListFromFile(AList, "C:\###\111.dat");
for ii := 1 to 10 do AList.Objects[ii - 1].Free;
AList.Clear;
finally
FreeAndNil(AList);
end; //try
end;


 
Севостьянов Игорь ©   (2002-12-26 17:04) [14]

gek © (26.12.02 15:11)
> тут в принципе можно файл записей сделать и читать все оттуда

Нельзя потому что String у него переменной длины

> Skier © (26.12.02 15:54)


> Примерно так :
>
> TMyObj = class
> private
> x,y : integer;
> S:string;
> end;

Это же класс, а надо record


 
Skier ©   (2002-12-26 17:12) [15]

>Севостьянов Игорь

> Это же класс, а надо record

Да ну ?! :)

Изначально в вопросе автор пишет про объекты....


 
Севостьянов Игорь ©   (2002-12-26 17:16) [16]

Хотя собственно для упрощения - это лучший выход (я о примере от Skier © (26.12.02 15:54))


 
Юрий Зотов ©   (2002-12-27 01:49) [17]

Вот что я тут набросал. Это потомок TStringList, который сам умееет сохранять "прицепленные" к своим строкам записи и в поток, и в DFM. Соответственно, и в файл тоже. Ну и читать, конечно.

Не тестировал (собирался, но спать очень хочется...). Но писал аккуратно, есть шанс, что заработает. Во всяком случае, компилируется "по нулям".

type
PMyRec = ^TMyRec;
TMyRec = record
X: integer;
Y: integer;
LenS: integer; // Хотя можно (и было бы лучше) обойтись без этого поля.
S: string
end;

TMyStrings = class(TStringList)
private
procedure ReadRecords(Reader: TReader);
procedure WriteRecords(Writer: TWriter);
function GetRecords(Index: integer): PMyRec;
procedure SetRecords(Index: integer; const Value: PMyRec);
protected
procedure ClearRecords; dynamic;
procedure DefineProperties(Filer: TFiler); override;
public
destructor Destroy; override;
procedure Clear; override;
procedure Delete(Index: Integer); override;
procedure SaveToStream(Stream: TStream); override;
procedure LoadFromStream(Stream: TStream); override;
property Records[Index: integer]: PMyRec read GetRecords write SetRecords;
end;

procedure TMyStrings.Clear;
begin
BeginUpdate;
try
ClearRecords;
inherited
finally
EndUpdate
end
end;

procedure TMyStrings.ClearRecords;
var
i: integer;
begin
BeginUpdate;
try
for i := Count - 1 downto 0 do Records[i] := nil
finally
EndUpdate
end
end;

procedure TMyStrings.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty("Records", ReadRecords, WriteRecords, Count > 0)
end;

procedure TMyStrings.Delete(Index: Integer);
begin
BeginUpdate;
try
Records[Index] := nil;
inherited
finally
EndUpdate
end
end;

destructor TMyStrings.Destroy;
begin
OnChange := nil;
OnChanging := nil;
ClearRecords;
inherited
end;

function TMyStrings.GetRecords(Index: integer): PMyRec;
begin
Result := PMyRec(Objects[Index])
end;

procedure TMyStrings.LoadFromStream(Stream: TStream);

function ReadString: string;
var
L: integer;
begin
Stream.ReadBuffer(L, SizeOf(L));
SetString(Result, nil, L);
Stream.Read(Pointer(Result)^, L)
end;

var
i: integer;
P: PMyRec;
begin
BeginUpdate;
with Stream do
try
Text := ReadString;
while Position < Size - 1 do
begin
ReadBuffer(i, SizeOf(i));
GetMem(P, SizeOf(TMyRec));
with P^ do
begin
ReadBuffer(X, SizeOf(X));
ReadBuffer(Y, SizeOf(Y));
S := ReadString;
LenS := Length(S)
end;
Records[i] := P
end
finally
EndUpdate
end
end;

procedure TMyStrings.ReadRecords(Reader: TReader);
var
i: integer;
P: PMyRec;
begin
with Reader do
begin
ReadListBegin;
BeginUpdate;
try
ClearRecords;
while not EndOfList do
begin
ReadListBegin;
i := ReadInteger;
GetMem(P, SizeOf(TMyRec));
with P^ do
begin
X := ReadInteger;
Y := ReadInteger;
LenS := ReadInteger;
S := ReadString
end;
Records[i] := P;
ReadListEnd
end
finally
EndUpdate
end;
ReadListEnd
end
end;

procedure TMyStrings.SaveToStream(Stream: TStream);

procedure WriteString(S: string);
var
L: integer;
begin
L := Length(S);
Stream.WriteBuffer(L, SizeOf(L));
Stream.WriteBuffer(Pointer(S)^, L)
end;

var
i: integer;
begin
WriteString(Text);
for i := 0 to Count - 1 do
if Records[i] <> nil then
with Stream, Records[i]^ do
begin
WriteBuffer(i, SizeOf(i));
WriteBuffer(X, SizeOf(X));
WriteBuffer(Y, SizeOf(Y));
WriteString(S)
end
end;

procedure TMyStrings.SetRecords(Index: integer; const Value: PMyRec);
begin
if Records[Index] <> Value then
begin
Changing;
if Records[Index] <> nil then
begin
Records[Index]^.S := "";
Finalize(Records[Index]^);
FreeMem(Records[Index], SizeOf(TMyRec));
end;
Objects[Index] := TObject(Value);
Changed
end
end;

procedure TMyStrings.WriteRecords(Writer: TWriter);
var
i: integer;
begin
with Writer do
begin
WriteListBegin;
for i := 0 to Count - 1 do
if Records[i] <> nil then
with Records[i]^ do
begin
WriteListBegin;
WriteInteger(i);
WriteInteger(X);
WriteInteger(Y);
WriteInteger(LenS);
WriteString(S);
WriteListEnd
end;
WriteListEnd
end
end;



 
Каспер ©   (2002-12-27 05:53) [18]

Люди спасибо огромное сейчас буду учить и осознавать!
рассмотрены будут все замечания и примеры.
Насчет объектов - я дал грубый пример для упрощения ответов.
На самом деле это пока запись. В ней куча полей так сказать Заголовок -где содержиться CRC тела, CMD (команда), Par1
Ну и тело - это набор байт переменной длинны в зависимости от команды.
В дальнейшем возможно это все перерастет в класс.
:(, но спиной чувствую что так и будет.
Терь по примерам научусь.
Всем еще раз спасибо и с наступающим.
Отдельное Спасибо! Юрию Зотову и Skier © за подробные примеры!


 
Каспер ©   (2002-12-27 09:29) [19]

А интересно...
память из под объектво не освобождается а просто обNILяется :)
или не все так понял...


 
Юрий Зотов ©   (2002-12-27 09:55) [20]

Освобождается. Присвоение Records[i] := nil приводит к вызову SetRecords(i, nil).


 
Каспер ©   (2002-12-27 10:22) [21]

МЛИН (просмотрел)! Не перестаю восхищаться.


 
Каспер ©   (2002-12-27 11:19) [22]

А чем отличаются методы
procedure TStack.SaveToStream(Stream: TStream);
procedure TStack.WriteBody(Writer: TWriter);
вернее когда или для чего они используются


 
Каспер ©   (2002-12-27 13:30) [23]

Юрий Зотов © (27.12.02 09:55)
Плищ разъясни что делают 2 метода
procedure TMyStrings.WriteRecords(Writer: TWriter); и
procedure TMyStrings.ReadRecords(Reader: TReader);
и как ты в них определяешь куда писать... Не вижу соответствия строки и принадлежащему ей объекту


 
Skier ©   (2002-12-27 13:43) [24]

>Каспер
Writer: TWriter и Reader: TReader это классы, которые использует
Delphi для записи и чтения свойств компонент в файл формы (.dfm)

Через DefineProperties
пользователь "указывает" Delphi как писать и читать из
файла свойства, имеющие пользовательскую, ("хитрую") структуру...
Кроме того через DefineProperties можно писать неопубликованные свойства...


 
Юрий Зотов ©   (2002-12-27 16:50) [25]

1. SaveToStream используется при записи в любой поток (например, в файл), а WriteRecords использует IDE при сохранении формы.


2. > Не вижу соответствия строки и принадлежащему ей объекту

При записи объекта сначала пишется его индекс (он же - индекс строки).


 
Каспер ©   (2003-01-05 06:55) [26]

Спасибо большое...
Хоть и с опозданием но сами понимаете. Новый год штука длинная.
Сам только узнал что 5 число :).
Вы вот разъяснили все. А в инете где нить есть еще примерчики или дока... можно по англицки. Нужно в самообразовательных целях.
С новым годом!
С наступающим рождеством!
Ох...


 
Yuri-7   (2003-01-05 07:42) [27]

Что-то все сложно у вас получилось. Если нет предубеждения на использование дополнительных компонентов, то для такого случая хорошо подойдет TkbmMemTable. Он не требует BDE и "плотно" хранит string данные. И длину string отдельно не надо хранить.

1. создаешь таблицу
2. объявляешь поля:
with kbm.fielddefs do
begin
Add("x",ftinteger);
Add("y",ftinteger);
Add("S",ftString,32000); или Add("S",ftMemo,1);
end;
CreateTable;
3. Записываешь данные, как в обычную таблицу
4. Сохраняешь, используя kbm.SaveToBinaryFile(..


 
Каспер ©   (2003-01-05 08:22) [28]

2 Yuri-7 (05.01.03 07:42)
Сам виноват.. :( надо было все сразу корректно описать.
Есть такая структура

TUserUIN=DWord;

THead = Record // заголовок пакета
CRC:DWord; //4
UIN:TUserUIN; //4
Command:byte;//1
Len:Word; //2 - длина основной части пакета (требуется)
End;

R1=record
x,y:integer;
s:string;
end;
R2=record
z:boolean;
s:string[255];
end;

TPData = Record //основное тело
Case Integer of
0:(User:R1);
1:(Status:R2);
2:(Mess:Rx);
3:(Data:...);
End;

TPacket = Record
Header :THead;
PData :TPData;
end;

!!!-1-!!! дело в том что структура не жесткая (на текущем этапе разработки требуется пока такая, в дальнейшем она может измениться и расшириться - на данные уже сохраненные по барабану, а вот на сам код модуля кторый зависит от этой стуктуры. Просто не хотелось бы его 50 раз переписывать)

Далее вступает в действие модуль Стек (разрабатывается для хранения получаемой из сети информации правильнее назвать его очередь... ). Пришел пакет. Я его запихиваю в стринглист (в Строку-UIN из пакета а в объект само тело). Ну и все остальные пакеты таким же образом дальше. Когда то (не обязательно сначала или с конца, возможно из середины пакеты будут уничтожаться).
Хотелось бы его исользовать таким образом....
В программе описал
var
Очередь:TStack;
begin
Очередь:=Tsack.Create(имя файла где она будет храниться при закрытии проги если она(очередь) не оказалась пуста)
....
end;

ну и пришел пакет, я его обрабатываю сам, как мне надо,
потом типа Очередь.AddPacket(MyPacket), он добавляет в Строку UIN из пакета, а все тело кидает в объект
Сохранить - сохраняет все в файл как есть...
В общем примерно так... :( Сори за сбивчивость



Страницы: 1 вся ветка

Текущий архив: 2003.01.16;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.023 c
1-49023
Аркадий
2003-01-04 00:40
2003.01.16
помогите


14-49218
Юров Владимир
2002-12-27 11:24
2003.01.16
MS SQL Server и конечный пользователь


1-49047
drin
2003-01-07 19:09
2003.01.16
Можно ли делать чтото вроде етого:


14-49247
Dimas
2002-12-26 17:23
2003.01.16
File not found: system.pas


14-49273
Johnny Smith
2002-12-24 12:11
2003.01.16
Давайте попинаем Борланд - благо, есть за что: