IStream — реализация составного файла

Интерфейс IStream поддерживает чтение и запись данных в потоковые объекты. В структурированном объекте хранилища объекты потока содержат данные, а хранилища предоставляют структуру. Простые данные можно записать непосредственно в поток, но чаще потоки являются элементами, вложенными в объект хранилища. Они похожи на стандартные файлы.

Спецификация IStream определяет больше функциональных возможностей, чем поддерживает реализация COM. Например, интерфейс IStream определяет потоки длиной до 2⁶⁴ байт, для которых требуется 64-разрядный указатель поиска. Однако реализация COM поддерживает только потоки длиной до 2 байтов (4 ГБ), а операции чтения и записи всегда ограничены 2bytes bytes за раз. Реализация COM также не поддерживает потоковую транзакцию или блокировку региона.

Чтобы создать простой поток на основе глобальной памяти, получите указатель IStream , вызвав функцию API CreateStreamOnHGlobal. Чтобы получить указатель IStream в составном объекте файла, вызовите stgCreateDocfile или StgOpenStorage. Эти функции извлекают указатель IStorage , с помощью которого можно вызвать CreateStream или OpenStream для указателя IStream . В любом случае используется тот же код реализации IStream .

Примечание

Реализация составного файла структурированного хранилища не выполняется в методе QueryInterface для ISequentialStream, но включает методы Read и Write через указатель интерфейса IStream .

 

Назначение

Вызовите методы IStream для чтения и записи данных в поток.

Так как потоковые объекты можно маршалировать в другие процессы, приложения могут совместно использовать данные в объектах хранилища без использования глобальной памяти. В реализации составного com-файла объектов потока пользовательские средства маршалинга в COM создают удаленную версию исходного объекта в новом процессе, когда два процесса имеют доступ к общей памяти. Таким образом, удаленной версии не нужно взаимодействовать с исходным процессом для выполнения своих функций.

Удаленная версия объекта потока использует тот же указатель поиска, что и исходный поток. Если вы не хотите предоставлять общий доступ к указателю поиска, используйте метод IStream::Clone , чтобы предоставить копию объекта потока для удаленного процесса.

Примечание

При создании объекта потока, превышающего кучу в памяти компьютера, и вы используете дескриптор HGLOBAL для объекта глобальной памяти, объект потока вызывает метод GlobalRealloc для внутренней обработки, когда ему требуется больше памяти. Так как GlobalRealloc всегда копирует данные из источника в место назначения, увеличение объекта потока с 20 ДО 25 МБ, например, требует большого количества времени. Это связано с размером копируемых приращений и ухудшается, если на компьютере меньше 45 МБ памяти из-за переключения диска.

Предпочтительным решением является реализация метода IStream , который использует память, выделенную VirtualAlloc вместо GlobalAlloc. Это может зарезервировать большой блок виртуального адресного пространства, а затем зафиксировать память в этом адресном пространстве по мере необходимости. Копирование данных не происходит, и память фиксируется только по мере необходимости.

Альтернативой GlobalRealloc является вызов метода IStream::SetSize в объекте потока, чтобы заранее увеличить выделение памяти. Однако это не так эффективно, как использование VirtualAlloc, как описано выше.

 

Методы

ISequentialStream::Read

Считывает указанное число байтов из объекта потока в память, начиная с текущего указателя поиска. Эта реализация возвращает S_OK, если во время чтения был достигнут конец потока. (Это то же самое, что поведение конца файла в файловой системе MS-DOS FAT.)

ISequentialStream::Write

Записывает указанное число из байтов в объект потока, начиная с текущего указателя поиска. В этой реализации объекты потока не являются разреженным. Все байты заполнения в конечном итоге выделяются на диске и назначаются потоку.

IStream::Seek

Изменяет указатель поиска на новое расположение относительно начала потока до конца потока или текущего положения поиска.

IStream::SetSize

Изменяет размер объекта-потока. В этой реализации нет никакой гарантии, что выделенное пространство будет непрерывным.

IStream::CopyTo

Копирует указанное число байтов из текущего указателя поиска в потоке до текущего указателя поиска в другом потоке.

IStream::Commit

Реализация составного файла IStream поддерживает открытие потоков только в прямом режиме, а не в режиме транзакций. Таким образом, метод не оказывает никакого влияния при вызове, кроме как для очистки всех буферов памяти до следующего уровня хранилища.

В этой реализации не имеет значения, если вы фиксируете изменения в потоках, вам потребуется только фиксация изменений для объектов хранилища.

IStream::Revert

Эта реализация не поддерживает потоки транзакций, поэтому вызов этого метода не оказывает никакого влияния.

IStream::LockRegion

Блокировка диапазона не поддерживается этой реализацией, поэтому вызов этого метода не оказывает никакого влияния.

IStream::UnlockRegion

Снимает ограничение доступа для диапазона байтов, ранее ограниченного с помощью IStream::LockRegion.

IStream::Stat

Извлекает структуру STATSTG для этого потока.

IStream::Clone

Создает новый объект потока с собственным указателем, который ссылается на те же байты, что и исходный поток.

Для простого режима IStream применяются следующие ограничения.

  • Поток является простым режимом, если он был создан или открыт из хранилища в простом режиме. Хранилище является простым режимом, если оно создается или открывается с помощью флага STGM_SIMPLE, установленного в параметре grfMode .
  • Методы Clone и CopyTo не поддерживаются.
  • Метод Stat поддерживается, но необходимо указать значение STATFLAG_NONAME.

IStream

IStorage

CreateStreamOnHGlobal

StgCreateDocfile

StgOpenStorage