Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Подземелье Магов
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  09:24[Войти] | [Зарегистрироваться]

Обсуждение материала
Упрощаем работу с потоками (TStream)
Полный текст материала


Другие публикации автора: Юрий Спектор

Цитата или краткий комментарий:

«... В Delphi введен механизм потокового ввода-вывода, значительно упрощающий наш нелегкий труд. Однако структура данных может быть достаточно сложна. К тому же, в разных проектах она наверняка будет различна. Все это заставляет нас снова и снова писать сотни строчек однообразного кода записи/чтения данных. ...»


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]685.7%
 
  Ничего особенно нового и интересного
[2]114.3%
 
  Написано неверно (обязательно укажите почему)
[3]00%
 
Всего проголосовали: 7

Оценка стиля изложения

  Все понятно, материал читается легко
[1]8100%
 
  Есть неясности в изложении
[2]00%
 
  Непонятно написано, трудно читается
[3]00%
 
Всего проголосовали: 8




Смотрите также материалы по темам:
[TStream] [Работа с потоками (TStream)] [RTTI] [Интерфейсы]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 15

20-06-2007 03:14
сообщение от автора материала
может для простых классов оно и не надо, но упускается возможность  создания свойств которые не должны записываться Stored false

Да, можно и такое предусмотреть. Совершенно несложно. Сделать проверочку на IsStoredProp.
 Ins


19-06-2007 23:47
извиняюсь за уточнение
может для простых классов оно и не надо, но упускается возможность  создания свойств которые не должны записываться
Stored false
а их использование удобно для инспектора объектов

например, часто делаю такую вещь

x1 - первая координата
x2 - вторая координата
dx= x2-x1 - разница между ними

пользователь может выбрать что ему вводить x2 или dx

но это наверное можно решить  допустим через флаг пропуска
для версионности всё же придётся пользоваться именами


07-04-2006 08:53
Маленькое замечание:
Описанный способ игнорирует
некоторые полезные классы, например TStrings,
которые записывают свои данные через
DefineProperties/DefineBinaryProperties.
Сообщение не подписано


05-04-2006 23:46
сообщение от автора материала
Я только не понял зачем наследование от TRttiObject.
Вызвав метод SaveToStream все свойства будут записаны в поток, никакого кода больше писать не надо. Собственно этому статья и посвящена.
И с каких это пор TGraphic и другие объекты VCL поддерживают интерфейс IStreamPersist?

TGraphic = class(TInterfacedPersistent, IStreamPersist)


По поводу сохранения более легких чем Tcomponent объектов.
А почему вы приводите код сохранения в поток компонента?
 Ins


05-04-2006 21:09
Я только не понял зачем наследование от TRttiObject.

Чтобы ограничить что можно писать в поток? Или для красоты?
И с каких это пор TGraphic и другие объекты VCL поддерживают интерфейс IStreamPersist?

Это извращение можно просто реализовать в виде функции
CoolSaveToStream(Object: TPersistent; Stream: TStream); overload;
CoolSaveToStream(Objects:array of TPersistent; Stream: TStream); overload;

И по поводу WriteClassProp. Если ваш объект не дерево, а сеть (т.е. содержат повторяющиеся ссылки на один и тот же объект), то этот код не прочитает корректно объект из потока. Надо запоминать, какие объекты уже сброшены в поток и при повторе записывать ссылку, а не свойства.

По поводу сохранения более легких чем Tcomponent объектов.
В любом случае чем возиться с M+ лучше ограничиться наследниками TPersistent (на то и название).

TEnvelope = class(TComponent)
fPersistent: TPersistent;
published
property Body: TPersistent read fPersistent write fPersistent;
end;

CoolSaveToStream(Object: TPersistent; Stream: TStream);
var E: TEnvelope;
begin
if Object is TComponent then
   Stream.WriteComponent(TComponent(Object))
else if Object is TPersistent then
begin
  E := TEnvelope.Create(nil);
  try
    E.Body := Object;
    Stream.WriteComponent(E);
  finally E.Free; end;
end;
end;

Надеюсь читатель сами сможете написать.


01-04-2006 05:38
Ins
Тут всё не так просто: если будем генерить исключение, то это ничем не лучше чем тупо читать несмотря ни на что. Хочется, чтобы старые файлы читались без проблем на новых версиях. Оставлять заботу о версиях на программисте, не самое лучшее решение, автоматический контроль надёжнее. Думаю простыми средствами это не решить, к примеру Borland с каждым свойством сохраняет его тип и даже перечислимые с множествами в текст переводит, что бы у нас было меньше проблем.
Я просто подумал о применимости данного модуля: для временного хранения информации в пределах версии (ну по сети например передавать между клиентом и сервером) - хорошо подходит (просто, компактно), для хранения документов или конфигов - очень плохо (абсолютно не переносим с версии на версию). Плюсы над стандартным сериализатором имеются только при сохранении большого количества однотипных объектов. Так может стоит (за счёт усложнения конечно) взять лучшее от обоих вариантов и сделать нечто позволяющее быстро работать с большими массивами объектов, но не имеющее проблем с версиями. Я это вижу как разделение метаинформации (информации о свойствах и типах) и собственно данных (значений свойств). То есть мы фактически должны сохранить часть RTTI информации в файл и при последующем чтении сравнивать её с тем что есть в EXE-шнике, все отличия лучше всего пропускать через специальный интерфейс который будет решать, что делать с этим свойством (чего очень не хватает в TReader-е, он просто генерит исключение на неизвестных свойствах). Так как это сравнение можно произвести всего один раз для данной версии файла, то разбор должен быть очень быстр, мы фактически пройдёмся по сгенерированному на этапе парсинга метаинформации массиву из PPropInfo (и указателей на функции для сложных свойств, которые в стандартном сериализаторе объявляются через DefineProperties) и подряд считаем свойства из потока. Никаких поисков свойств в таблицах (и строковых значений для перечислимых), никакой информации о типе итд, только данные, одно за другим.
В идеале это должно быть совместимо со стандартным механизмом (что бы формочки например сохранять).

А кто ни будь знает как с этим делом в .NET дела обстоят? Желательно ссылку хорошую на детальное описание сериализации в .NET.
 DRON


31-03-2006 09:26
сообщение от автора материала
DRON:
Спасибо за совет. Как Вы считаете следующий метод подойдет?

TRttiObject = class(TInterfacedPersistent, IStreamPersist)
  protected
    class function ClassSignature: String; virtual;
  public
    ...
  end;

class function TRttiObject.ClassSignature: String;
begin
  Result:='';
end;


При записи класса вначале записывается результат функции ClassSignature. При чтении, считываемое значение сравнивается с ClassSinature, в случае совпадения данные считываются дальше, иначе возбуждается исключение. Но в этом случае программист должен при внесении изменений, изменить и результат функции ClassSignature, например если раньше он был 'MySign v1.0', сделать например 'MySign v1.1'.
 Ins


30-03-2006 13:28
И используют метод потока ReadComponent который все написанное в статье и реализует и даже больше.
Больше я так понимаю относится к размеру получаемого файла? Стандартная сериализация конечно хорошая вещь, но при сохранении тысяч простых объектов, там пишется слишком много служебной информации.

To Ins:
Неплохо было бы добавить хоть какой-то контроль версий, а то замучаешься конвертеры из старых в новые версии писать: добавил поле и старые файлы уже не читаются. Может стоит сделать как в TReader/Writer-е: сохранять имена свойств, но делать это не в каждом объекте, а один раз в начале файла, тогда и гибкость будет и компактность.

Кто бы написал аналогичную сериализацию для record-ов...
 DRON


30-03-2006 06:21
Собственно обычно работают с TComponent и его наследниками.
И используют метод потока ReadComponent который все написанное в статье и реализует и даже больше. При необходимости более гибкой работы используют TReader и TWrite. Собственно статья прилогатся http://www.rsdn.ru/article/delphi/serialization.xml


30-03-2006 03:46
Полезная вещь.
Действительно, бывает надобность писать в поток простые классы, это дает возможность делать программы с "объектным" сохранением данных, и готовый пример в этом случае - большая помощь.


29-03-2006 06:54
Для panda

Описанный здесь способ, лучше того о котором Вы говорите тем, что он может быть применен к простейшим классам, которые не обязательно должны быть наследниками TComponent.

Кроме того, статья интересна тем, что дает механизм работы с информациях о типах свойств класса в run-time. Это может быть полезно для тех, кто пытается делать редакторы свойств, подобные Object Inspector и является хорошим дополнением к статье http://www.delphikingdom.com/asp/viewitem.asp?catalogid=565
 mmu


28-03-2006 02:01
Мне этот материал может в будущем пригодится. Часто бывают такие ситуации когда надо сохранять в поток не TComponent и тогда указаная методика может пригодится. Я знал что так можно сделать, но потратил бы не мало времени на написание самостоятельно. Очень удобно иметь возможность взглянуть на готовый пример.


28-03-2006 00:37
сообщение от автора материала
Panda:
Принципиально - ничем, разве что экономичнее, скажем так, это альтернатива. Я выложил этот материал, потому что сам им пользуюсь, и не только потому, что свое всегда приятнее. Вот я и решил, что это может быть полезным не только мне.
 Ins


27-03-2006 23:30
2 Юрий Спектор:
Не могли бы Вы пояснить, чем описанный здесь способ принципиально лучше использования TComponent (поддержка которого в TStream уже есть)?


27-03-2006 09:24
Как раз искал как сохранить запись, содержащий массивы с динамическим AnsiString в файл, надеюсь материал поможет....


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Зимой — белый, летом — серый. Кто?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования