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

Вниз

Запись/восстановление TComponent из строки.   Найти похожие ветки 

 
w666w   (2005-06-13 14:37) [0]

Добрый день.

Есть необходимость передавать компонент для хранения в базе данных в инете. И соответсвенно восстанавливать из этой базы.

Для этого надо соответсвенно "срез" этого компонента каким-то обазом превратить в строку. Без проблем можно это сделать, записав предварительно его методом WriteComponentResFile в файл, потом прочесть весь файл в строку и после этого уже передавать.  Но надо без файла и этих лишних движений. Соответственно надо и восстанавливать обратно из строки в компонент.

Помогите пожалуйста. За пример кода буду очень благодарен.


 
Stanislav ©   (2005-06-13 14:47) [1]

TMemoryStream и Blob поля в базе.


 
w666w   (2005-06-13 14:53) [2]

Насчет базы нет проблем. Насколько понимаю записать компонент в поток:

procedure Save_struct(var _t:TComponent);
var _M: TMemoryStream;
begin
_M := TMemoryStream.Create;
 Try
   _M.WriteBuffer( _t, sizeof(_t) );
   _M.
   _M.SaveToFile(êóäà);
 finally
_M.Free;
end;
end;

Поправьте если не так.

А как из TMemoryStream в строку забрать?


 
w666w   (2005-06-13 14:54) [3]

Неверно код написал.

procedure Save_struct(var _t:TComponent);
var _M: TMemoryStream;
begin
_M := TMemoryStream.Create;
 Try
   _M.WriteBuffer( _t, sizeof(_t) );
 finally
_M.Free;
end;
end;


 
Stanislav ©   (2005-06-13 15:01) [4]

А зачем в строку?
procedure Save_struct(var _t:TComponent);
var _M: TMemoryStream;
begin
_M := TMemoryStream.Create;
Try
  _M.WriteBuffer( _t, sizeof(_t) );
_M.Position:=0;
 TBlobField(MyField).LoadFromStream(_M);
finally
_M.Free;
end;
end;


 
w666w   (2005-06-13 15:05) [5]

База находитя на удаленном хосте (в инете). Туда надо передавать срез компонента в каком-то виде. Архив, текст... как угодно назовите... Но главная задача - не создавать файлы на диске перед отправкой. И соотв. после скачки из удаленной базы перед восстановлением компонента тоже файлов не создавать.

Вот такая вот задачка...


 
Stanislav ©   (2005-06-13 15:08) [6]

Stanislav ©   (13.06.05 15:01) [4]
Так файл и не будет создаваться. Вы считываете в поток, а потом поток прямо в базу, как в примере:
procedure Save_struct(var _t:TComponent);
var _M: TMemoryStream;
begin
_M := TMemoryStream.Create;
Try
 _M.WriteBuffer( _t, sizeof(_t) );
_M.Position:=0;
TBlobField(MyField).LoadFromStream(_M);
finally
_M.Free;
end;
end;


 
w666w   (2005-06-13 15:36) [7]

На сервере идет аутентификация пользователя, после успешной - запись/чтение из blob поля и передача обратно либо кода успешного сохранения, либо непосредственно кода компонента. Просто напрямую с базой работать нельзя, таковы условия задачи. Поэтому прийдется соединяться по HTTP и проводить много разных манипуляций которые здесь не имеет значения описывать.

Итог: нужно иметь в распоряжении строку, которую постом подцеплять к HTTP соединению. То есть надо реализовать что-то типа:

function GetComponentString(aComponent : TComponent) : string;
var fResult : string;
   _M: TMemoryStream;
begin
 fResult := "";
 _M := TMemoryStream.Create;
 try
   _M.WriteBuffer(aComponent, sizeof(aComponent));
   fResult := .............
 finally
   _M.Free;
 end;
 Result := fResult;
end;

Вот прошу помочь с моментом
fResult := ..........

Ну и соотв. Обратная процедура восстановления космонента из строки, которая вернется по HTTP.


 
Просто Джо ©   (2005-06-13 15:51) [8]

Можно сделать таким образом:


function GetComponentString (AComponent: TComponent): string;
var
 AStream: TMemoryStream;
 AStrStream: TStringStream;
begin
 Result := "";

 AStrStream := TStringStream.Create("");
 try

   AStream := TMemoryStream.Create;
   try
     AStream.WriteComponent(AComponent);
     AStream.Seek(0,soFromBeginning);
     ObjectBinaryToText(AStream,AStrStream);
   finally
     AStream.Free;
   end;

   Result := AStrStream.DataString;
 finally
   AStrStream.Free
 end;
end;


 
Stanislav ©   (2005-06-13 15:57) [9]

Если содержание строки не имеет смысла, то в принципе, тот же поток можно отобразить в виде строки.
Например:
function GetComponentString(aComponent : TComponent) : string;
var fResult : string; MM:TMemo;
  _M: TMemoryStream;
begin
fResult := "";
_M := TMemoryStream.Create;
MM:=TMemo.Create(Self);
try
  _M.WriteBuffer(aComponent, sizeof(aComponent));
_M.Position:=0;
 MM.LoadFromStream(_M);
  fResult := MM.text;
finally
  MM.Free
  _M.Free;
end;
Result := fResult;
end;
Для удобства я привел пример с MEMO, но вообще можно результат потока считать прямо в строку.


 
Stanislav ©   (2005-06-13 15:59) [10]

Stanislav ©   (13.06.05 15:57) [9]
>Если содержание строки не имеет смысла...
Имел ввиду визуального :-)


 
Просто Джо ©   (2005-06-13 15:59) [11]

Дополнение к [8] Просто Джо ©   (13.06.05 15:51)

А вот так обратное преобразование:

procedure LoadComponentFromString (AComponent: TComponent; AString: string);
var
 AStream: TMemoryStream;
 AStrStream: TStringStream;
begin
 AStrStream := TStringStream.Create(AString);
 try
   AStream := TMemoryStream.Create;
   try
     ObjectTextToBinary(AStrStream,AStream);
     AStream.Seek(0,soFromBeginning);
     AStream.ReadComponent(AComponent);
   finally
     AStream.Free;
   end;
 finally
   AStrStream.Free
 end;
end;


 
Просто Джо ©   (2005-06-13 16:05) [12]

Примечание к моим постам в этой ветке.
Разумеется, для того, чтобы ваш объект умел "правильно" сериализироваться, т.е., правильно сохранять свое состояние, необходимо самому об этом позаботиться. Предполагается, что вы уже это сделали, если же нет, то, чтобы долго не объяснять, ищи статью "Сериализация объектов в Делфи" или что-то в таком роде, в Инете имеется.


 
w666w   (2005-06-13 16:29) [13]

> Просто Ждо

Большое спасибо, код рабочий. Единственное, что после сохранения объекта в строку он из этой же строки восстанавлмваться не хочет почему то... Наверное проблемы с сериализацией как уже было сказано...

> Stanislav
Метод, предложенный Просто Джо хорош, но в нем есть 1 минус. Для моей задачи главное - минимальный размер результирующей строки (для уменьшения времени на загрузку/сохранение). То есть визуальный смысл строки не имеет абсолютно никакого смысла. А в примере Просто Джо размер искуственно увеличен за счет читаемости. Пытаюсь реализовать приведенный Вами пример, никак не получается:

function SaveComponentToString(aComponent : TComponent) : string;
var fResult : string;
   _M: TMemoryStream;
   fStrings : TStrings;
begin
 fResult := "";
 _M := TMemoryStream.Create;
 fStrings := TStrings.Create;
 try
   _M.WriteBuffer(aComponent, sizeof(aComponent));
   _M.Position := 0;
   fStrings.LoadFromStream(_M);
   fResult := fStrings.Text;
   ShowMessage(fStrings.Text);
 finally
   _M.Free;
   fStrings.Free;
 end;
 Result := fResult;
end;

Убрал мемо, но с ним было та же ошибка:
на строке fStrings.LoadFromStream(_M); постоянно EAbstractError

Что не так?


 
Erik1 ©   (2005-06-13 16:58) [14]

А почему пример другой взял? В исходном примере ReadComponent и WriteComponent используется, их можно прямо в StringStream читать и писать.


 
Stanislav ©   (2005-06-13 17:03) [15]

w666w   (13.06.05 16:29) [13]
TStringList попробуйте, там вобщем можно посмотреть как это реализованно и обойтись без него.


 
w666w   (2005-06-13 18:18) [16]

Нашел именно то решение, которое искал:

function SaveComponentToString(aComponent : TComponent) : string;
var AStrStream: TStringStream;
begin
 Result := "";
 AStrStream := TStringStream.Create("");
 try
   AStrStream.WriteComponent(aComponent);
   Result := AStrStream.DataString;
 finally
   AStrStream.Free;
 end;
end;

function LoadComponentFromString(AComponent: TComponent; AString: string) : boolean;
var
 AStrStream: TStringStream;
 fResult : boolean;
begin
 fResult := false;
 AStrStream := TStringStream.Create(AString);
 try
   AStrStream.ReadComponent(AComponent);
   fResult := true;
 finally
   AStrStream.Free;
 end;
 Result := fResult;
end;

Все оказалось довольно просто. Огромное спасибо всем кто помог. Удачи!



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

Форум: "Основная";
Текущий архив: 2005.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.049 c
1-1118912020
Alias
2005-06-16 12:53
2005.07.11
Подайте идею как искать причину stack overflow


3-1117430946
pavel_guzhanov
2005-05-30 09:29
2005.07.11
Сжатие картинки jpeg при помещении ее в базу


11-1101196866
mdw
2004-11-23 11:01
2005.07.11
Нужен KOLICS


6-1112681299
peppo
2005-04-05 10:08
2005.07.11
Коннект "решительно отвергается"


3-1117441868
Yurisimus
2005-05-30 12:31
2005.07.11
Сохранение файла *.xls как *.dbf и создание индекса...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский