Форум: "Основная";
Текущий архив: 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.01 c