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

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

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

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

Примечание.

Реализация составного файла структурированного хранилища не выполняется в методе QueryInterface для ISequentialStream, но включает методы чтения и записи с помощью указателя интерфейса 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