Публикации
Последние новости:
 
Высокие технологии
Technology
Компьютерное железо
Программное обеспечение
Компьютерная безопасность
Операционные системы
Компьютерный справочник
БД
Интернет сегодня
AudioТехника
Средства связи
Весь спектр цифровой техники
Мир авто
Бизнес-финансы
Всё о культуре
ПроСпорт
Всё о компьютерах
Детское чтение
Мировые телекоммуникации
Пресс-релизы
 
Статьи
Мир культуры
Интересно о спорте
Покупаем:
ТурТранс
Для прекрасных дам
Усадьба, дом
 

Платный хостинг от провайдера HostSpace.com.ua - хостинг, регистрация доменов. Поддержка PHP, MySQL, почта - в каждом тарифном плане.





СОМ-хранилища: подпольная файловая система

Рано или поздно перед многими программистами встает вопрос - в каком формате хранить данные своей программы? Хорошо, если сохраняемая информация - это записи с фиксированной длиной. А если нужно записать разнородные данные - да еще в одном файле (чтоб потом не разбираться с десятком-другим файлов)?









Тут на помощь приходит сама Windows с технологией структурированного хранилища данных.

Определения

Структурированные хранилища данных - это файлы особой "самодокументированной" структуры, в которых могут мирно уживаться разнородные данные (от простого текста до фильмов, архивов и… программ). Поскольку эта технология является неотъемлемой частью Windows, доступ к ней возможен из любого поддерживающего технологию COM средства программирования. Одним из таких инструментов является Delphi, на основе которого будет описана технология доступа к структурированным хранилищам данных.

COM-хранилища напоминают иерархическую файловую систему. Так, в них есть корневое хранилище (Root Entry), в котором могут содержаться как отдельные потоки ("файлы"), так и хранилища второго уровня ("каталоги"). В них, в свою очередь,- хранилища третьего уровня и т.д. Управление каждым хранилищем и потоком осуществляется посредством отдельного экземпляра интерфейса: IStorage - для хранилищ и IStream - для потоков. Рассмотрим конкретнее некоторые операции, реализуемые этими интерфейсами.

Создание и открытие хранилищ

Создание хранилищ осуществляется с использованием функции StgCreateDocFile из модуля ActiveX.pas:

function StgCreateDocfile (pwcsName: POleStr; grfMode: Longint;
reserved: Longint; out stgOpen: IStorage): HResult; stdcall;

где:

  • pwcsName - название хранилища (т. е. название файла);
  • grfMode - флаги доступа (комбинация значений STGM_*);
  • reserved - он и в Африке RESERVED;
  • StgOpen - ссылка на интерфейс IStorage нашего главного хранилища.
  • Результат функции как всегда транслируем в исключения Delphi посредством OleCheck.

    Для открытия хранилища используется функция StgOpenStorage:

    function StgOpenStorage (pwcsName: POleStr; stgPriority: IStorage;
    grfMode: Longint; snbExclude: TSNB; reserved: Longint;
    out stgOpen: IStorage): HResult; stdcall;

    параметр stgPriority указывает на ранее открытый экземпляр главного хранилища (почти всегда nil).

    Когда хранилище открыто…

    Рассмотрим более подробно методы интерфейса IStorage.

    Создание потока - IStorage.CreateStream.

    function CreateStream (pwcsName: POleStr; grfMode: Longint; reserved1: Longint;reserved2: Longint; out stm: IStream): HResult; stdcall;

    Открытие потока - IStorage.OpenStream:

    function OpenStream (pwcsName: POleStr; reserved1: Pointer; grfMode: Longint;reserved2: Longint; out stm: IStream): HResult; stdcall;

    параметры:

  • pwcsName - название потока;
  • grfMode - флаги доступа;
  • reserved1, reserved2 - соответственно;
  • stm - указатель на созданный поток.
  • Можем приступать к чтению (записи) данных из (в) потоков посредством интерфейсов IStream. Тут можно заметить до боли знакомые методы работы с потоками: Read, Write, Seek… - а если так, то почему бы не перевести эти методы в более простую и понятную объектную форму? Для этого воспользуемся наработками Borland, собранными в модуле AxCtrls.pas (точнее - классом TOleStream, который интерпретирует вызовы методов интерфейса IStream в соответствующие методы класса Tstream).

    А чтоб не быть голословным - приведу небольшой пример:

    Implementation
    Uses ActiveX,AxCtrls,ComObj;
    procedure TForm1.Button1Click (Sender: TObject);
    var Stg:IStorage;
    Strm:IStream;
    OS:TOleStream;
    S:String;
    begin
    OleCheck (StgCreateDocfile (Testing.stg,STGM_READWRITE
    or STGM_SHARE_EXCLUSIVE,0,Stg));
    OleCheck (Stg.CreateStream (Testing,STGM_READWRITE
    or STGM_SHARE_EXCLUSIVE,0,0,Strm));
    OS:=TOleStream.Create (Strm);
    try
    S:=This is the test;
    OS.WriteBuffer (Pointer (S)^,Length (S));
    finally
    OS.free;
    Strm:=nil;
    Stg:=nil;
    end;
    end;
    end.
    
    

    В этом фрагменте мы создаем новое хранилище с одним потоком, в который записываем строку S. Естественно, ничто не мешает нам написать например:

    Image1.Picture.Bitmap.SaveToStream (OS)
    
    

    - и тем самым записать в поток Testing изображение (вот она - "универсальная мусоросвалка"). Теперь ненадолго отвлечемся от Delphi и посмотрим на наш файл с точки зрения, скажем, Far (или VC)… Посмотрели? Если там же открыть любой документ Word (Excel), убедимся, что структура будет такой же, что и в нашем файле. Проверка принадлежности файла к формату хранилищ проводится с использованием функции StgIsStorageFile из ActiveX.pas:

    function StgIsStorageFile (pwcsName: POleStr): HResult; stdcall;

    Результат:

  • S_OK (0) - файл является хранилищем данных;
  • S_FALSE (1) - файл не является хранилищем.
  • Кроме того, эта функция может принимать значения STG_E_INVALIDFILENAME (если имя задано неправильно) и STG_E_FILENOTFOUND (если файла с таким именем не существует).

    Чтение

    Чтение данных из хранилища производится так же, как и чтение из стандартного потока Delphi. Все, что для этого требуется, это создать объект TOleStream с использованием возвращаемого функцией IStorage.OpenStorage значения stm:

    procedure TForm1.Button2Click (Sender: TObject);
    var Stg:IStorage;
    Strm:IStream;
    OS:TOleStream;
    S:String;
    begin
    OleCheck (StgOpenStorage (Testing.stg,nil,STGM_READWRITE
    or STGM_SHARE_EXCLUSIVE, nil,0,Stg));
    OleCheck (Stg.OpenStream (Testing,0,STGM_READWRITE
    or STGM_SHARE_EXCLUSIVE,0,Strm));
    OS:=TOleStream.Create (Strm);
    try
    SetLength (S,OS.Size);
    OS.ReadBuffer (Pointer (S)^,OS.Size);
    Edit1.Text:=S;
    finally
    OS.free;
    Strm:=nil;
    Stg:=nil;
    end;
    end;
    
    

    После выполнения этого кода мы увидим в Edit1 ранее записанное нами: "This is the test".

    Исследование хранилищ

    Хорошо… мы создали хранилище, записали в него данные и прочитали их. Но мы сделали это, ЗНАЯ имя потока, в котором записаны наши данные. Но как быть, если мы не знаем структуры хранилища? Для этого в интерфейсе IStorage предусмотрен механизм перечисления элементов хранилища - он содержится в интерфейсе IEnumStatStg (указатель на который возвращается функцией IStorage.EnumElements):

    function EnumElements (reserved1: Longint; reserved2: Pointer; reserved3: Longint;out enm: IEnumStatStg): HResult; stdcall;

    Употребление этой функции происходит так:

    OleCheck (Stg.EnumElements (0,nil,0,Enum));
    
    

    После этого используем только методы интерфейса IenumStatStg (Next, Skip, Reset, Close). Самым важным из этих методов на данный момент является для нас метод Next:

    Next (celt:Longint; out elt; pceltFetched: PLongint): HResult; stdcall;

    Он может принимать следующие параметры:

  • Celt - количество элементов структуры, которое будет извлечено при его вызове;
  • Elt - массив-приемник элементов типа TstatStg;
  • PceltFetched - указатель на переменную, в которую будет записано действительное количество извлеченных элементов.
  • Для примера воспользуемся любым doc-файлом и перечислим его элементы:

    procedure TForm1.Button2Click (Sender: TObject);
    var Stg:IStorage;
    Enum:IEnumStatStg;
    Data:TStatStg;
    begin
    OleCheck (StgOpenStorage (D:.doc,nil,STGM_READWRITE
    or STGM_SHARE_EXCLUSIVE,nil,0,Stg));
    OleCheck (Stg.EnumElements (0,nil,0,Enum));
    try
    While Enum.Next (1,Data,nil)=S_Ok do
    ListBox1.Items.Add (Format (%s
    (%d),[Data.pwcsName,Data.cbSize]));
    finally
    Stg:=nil;
    Enum:=nil;
    end;
    end;
    
    

    Структура TStatStg содержит, помимо pwcsName и cbSize, следующие поля:

    pwcsName: POleStr; название потока или хранилища
    dwType: Longint; тип элемента (флаги типа STGTY_*)
    cbSize: Largeint; размер конкретного элемента
    mtime,ctime,atime: TFileTime; дата модификации, создания, последнего доступа
    grfMode: Longint; флаг доступа
    grfLocksSupported: Longint; не используется в хранилищах
    clsid: TCLSID; идентификатор класса хранилища
    grfStateBits: Longint; статусные биты
    reserved: Longint; зарезервирован

    Описанные интерфейсы и методы помогут вам не только использовать уже существующие COM-хранилища (такие как документы MS Office), но и создавать собственные,- благодаря чему ваши данные будут храниться в компактном и согласованном виде.



    Михаил Продан



    www.cybersecurity.ru

    Операционные системы 13-03-2007

    Возможности нового Планировщика заданий в Windows Server 2008 28-07-2008 Операционные системы
    Планировщик заданий (Task scheduler) в Windows Server 2008 подвергся значительной модификации по сравнению с предыдущими версиями Windows Server. Теперь ключевыми элементами запланированных заданий стали триггеры (Triggers), действия (Actions), условия (Conditions) и параметры (Settings).Набор настроек триггеров и действий запланированного задания в Windows Server 2008 значительно расширился. Среди стандартных триггеров – возможность начинать зад...


    Как намертво заблокировать процедуру входа в Windows Vista 02-07-2008 Операционные системы
    Недавно в одной из статей в рамках серии обзоров возможностей Windows Vista я показал, как можно вручную войти в систему Windows Vista на домашнем компьютере: «Как обойти процедуру входа в Windows Vista». Несмотря на то, что данная там инструкция предназначалась для людей, единолично использующих Windows Vista на домашней машине, множество читателей не разделили мнение о том, что можно оставить систему незащищенной.Основываясь на этих отзывах, я ...


    Оптимизация и настройка служб Windows Vista 25-06-2008 Операционные системы
    По умолчанию окно Диспетчера задач (Task Manager) выглядит так, как показано на этом снимке. В нём отображены только процессы, работающие под вашей пользовательской учётной записью. Чтобы увидеть также и процессы, работающие под служебными учётными записями, нужно нажать кнопку Отображать процессы всех пользователей (Show processes from all users), которая находится в нижнем левом углу окна.Используйте Диспетчер задач для того, чтобы увидеть все ...


    Персонализация функции быстрого поиска в меню «Пуск» Vista 19-05-2008 Операционные системы
    К счастью, функцию быстрого поиска в меню «Пуск» (Start) Vista можно сделать еще удобнее, объединив ее с поиском Google. Для этого придется воспользоваться Редактором локальной групповой политики (Local Group Policy Editor). Чтобы его запустить, нажмите клавиши [Windows]+[R], введите в диалоговом окне «Открыть» (Run) фразу gpedit.msc и нажмите «OK». После этого появится диалоговое окно системы Контроля учетных записей пользователей (UAC), в котор...

    Использование утилиты проверки диска Check Disk в системе Windows Vista 13-05-2008 Операционные системы
    Утилита «Проверка диска» (Check disk) операционной системы Windows Vista позволяет проверить целостность диска, выявить повреждённые сектора и восстановить информацию.Щёлкните правой кнопкой на пиктограмме нужного диска и в раскрывшемся контекстном меню выберите пункт «Свойства» (Properties), как показано на изображениях A и B.Изображение A.Изображение B.В диалоговом окне «Свойства» (Properties) перейдите на вкладку «Сервис» (Tools) и нажмите кно...

    Выборочное отключение контроля учетных записей (UAC) для проверенных приложений в Windows Vista 13-05-2008 Операционные системы
    Недавно я прочёл копию статьи Базы знаний Microsoft «Как отключить Контроль учётных записей пользователей для отдельных приложений» (How To Disable The User Account Control Prompt For Certain Applications), в которой продемонстрировано, как выборочно отключить контроль учётных записей (UAC) для конкретных программ при помощи пятой версии пакета средств обеспечения совместимости приложений Microsoft Application Compatibility Toolkit. Этой инструкц...
     
    При любом использовании материалов сайта ссылка на сайт www.archive.com.ua обязательна.
    Rambler's Top100 Рейтинг@Mail.ru