Программирование - это просто
Advertisement
Главная arrow C#, Delphi, VB, F#, Web и пр. arrow Прочее программирование arrow Delphi: Маленькие хитрости arrow Delphi: как сериализовать строку в поток (Stream, string, WriteBuffer, ReadBuffer, Serialize)
23.05.2019 г.
Главное меню
Главная
Системный подход
Интернет магазин
Биржевые роботы
Программные продукты
Математика и информатика
1С:Предприятие
C#, Delphi, VB, F#, Web и пр.
Искусственный интеллект
Услуги
Ча. Во. (FAQ)
Платный раздел
Наука для чайников
Разное
Размышления
Карта сайта
Друзья сайта
Excel-это не сложно
Все о финансах
Delphi: как сериализовать строку в поток (Stream, string, WriteBuffer, ReadBuffer, Serialize) Печать E-mail
Автор megabax   
22.10.2009 г.
New Page 1

Delphi: как сериализовать строку в поток (Stream, string, WriteBuffer, ReadBuffer, Serialize)

В Delphi нельзя напрямую сериализовать строку (String) в поток. В частности, такой код работать не будет:

procedure TEasyGameContainer.Serialize(AStream:TStream);
var i,cn:integer; lClassName:string;
begin
   inherited Serialize(AStream);
   cn:=FObjects.Count-1;
   AStream.Write(cn,sizeof(cn));
   for i:=0 to cn do
   begin
      lClassName:=TEasyGameObject(FObjects[i]).ClassName;
     AStream.Write(lClassName,sizeof(lClassName));
     TEasyGameObject(FObjects[i]).Serialize(AStream);
   end;
end;

procedure TEasyGameContainer.Unserialize(AStream:TStream);
var i,cn:integer; lClassName:string;
      lClass:TPersistentClass;
      lObject:TPersistent;
begin
    inherited Unserialize(AStream);
   AStream.Read(cn,sizeof(cn));
   for i:=0 to cn do
   begin
      AStream.Read(lClassName,sizeof(lClassName));
      lClass:=FindClass(lClassName);
      lObject:=lClass.Create;
      TEasyGameObject(lObject).Unserialize(AStream);
      AddGameObject(TEasyGameObject(lObject));
    end;
end;

так как команда

AStream.Read(lClassName,sizeof(lClassName))

прочитает в переменную "мусор". Все дело в том, что при выполнении команды

AStream.Write(lClassName,sizeof(lClassName));

в поток пишется не сама строка, а только 4-байта ее адреса. При чтении так же читаются эти самые 4 байта. А куда потом будет указывать этот адрес - неизвестно, но явное не на той текст строки, который мы хотели записать в поток.

Что же делать?  Правильно писать строку в поток и считывать ее оттуда так:

procedure SerializeString(AString:string; AStream:TStream);
var l:integer;
begin
     l:=Length(AString);
    AStream.Write(l,Sizeof(l));
    if l>0 then AStream.WriteBuffer(AString[1],l);
end;

function UnserializeString(AStream:TStream):string;
var l:integer; s:string;
begin
   AStream.Read(l,Sizeof(l));
   if l>0 then
   begin
      SetLength(s,L);
     AStream.ReadBuffer(s[1],L);
   end;
   Result:=s;
end;

Объявив эту процедуру и функцию, мы можем переделать неработающий код:

procedure TEasyGameContainer.Serialize(AStream:TStream);
var i,cn:integer; lClassName:string;
begin
    inherited Serialize(AStream);
    cn:=FObjects.Count-1;
   AStream.Write(cn,sizeof(cn));
   for i:=0 to cn do
   begin
      lClassName:=TEasyGameObject(FObjects[i]).ClassName;
      SerializeString(lClassName,AStream);
     TEasyGameObject(FObjects[i]).Serialize(AStream);
   end;
end;

procedure TEasyGameContainer.Unserialize(AStream:TStream);
var i,cn:integer; lClassName:string;
       lClass:TPersistentClass;
       lObject:TPersistent;
begin
     inherited Unserialize(AStream);
    AStream.Read(cn,sizeof(cn));
    for i:=0 to cn do
    begin
        lClassName:=UnserializeString(AStream);
        lClass:=FindClass(lClassName);
        lObject:=lClass.Create;
       TEasyGameObject(lObject).Unserialize(AStream);
       AddGameObject(TEasyGameObject(lObject));
    end;
end;
Последнее обновление ( 16.11.2011 г. )
 
« След.   Пред. »
 
© 2019 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги
Мы принимаем
Банковские карты
Оплатите покупку в интернет-магазине банковскими картами VISA и Mastercard любого банка.
узнать больше
Электронный кошелек
Моментальная оплата покупок с помощью вашего электронного кошелька RBK Money.
узнать больше
Банковский платеж
Оплатите покупку в любом российском банке. Срок зачисления средств на счет - 3-5 рабочих дней.
узнать больше
Денежные переводы
Оплата покупок через крупнейшие системы денежных переводов CONTACT и Unistream.
узнать больше
Почтовые переводы
Оплатите покупку в любом отделении Почты России. Срок зачисления платежа - 3-4 рабочих дня.
узнать больше
Платежные терминалы
Оплата покупок в терминалах крупнейших платежных систем в любом городе России - быстро и без комиссии.
узнать больше