Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];

Вниз

Сохранение/чтение Объектов 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.008 c
3-48850
volph7777
2002-12-23 16:20
2003.01.16
почему SQL-запрос по разному выполняется


1-49092
duke2
2003-01-02 07:06
2003.01.16
Вопрос знатокам формата RTF


3-48932
qwerty2
2002-12-22 00:56
2003.01.16
Вопрос по SQL (заглавные/строчные буквы)


14-49256
DOC97
2002-12-26 01:03
2003.01.16
15 WMZ - за прогу


14-49304
TTCustomDelphiMaster
2002-12-27 16:07
2003.01.16
А есть еще форумы по Дельфи такие оживленные как этот,





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский