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, как описано выше.
Методы
-
Считывает указанное число байтов из объекта потока в память, начиная с текущего указателя поиска. Эта реализация возвращает S_OK, если во время чтения достигнут конец потока. (Это то же самое, что и поведение конца файла, найденное в файловой системе MS-DOS FAT.)
-
Записывает указанное число из байтов в объект потока, начиная с текущего указателя поиска. В этой реализации объекты потоков не разрежены. Все байты заливки в конечном итоге выделяются на диске и назначаются потоку.
-
Изменяет указатель поиска на новое расположение относительно начала потока до конца потока или текущего положения поиска.
-
Изменяет размер объекта потока. В этой реализации нет никаких гарантий, что выделенное пространство будет смежным.
-
Копирует указанное число байтов из текущего указателя поиска в потоке до текущего указателя поиска в другом потоке.
-
Реализация составного файла IStream поддерживает открытие потоков только в прямом режиме, а не в режиме транзакций. Поэтому метод не действует при вызове, кроме очистки всех буферов памяти до следующего уровня хранилища.
В этой реализации не имеет значения, если вы фиксируете изменения в потоках, вам потребуется только фиксация изменений для объектов хранилища.
-
Эта реализация не поддерживает трансактированные потоки, поэтому вызов этого метода не действует.
-
Блокировка диапазона не поддерживается этой реализацией, поэтому вызов этого метода не действует.
-
Удаляет ограничение доступа для диапазона байтов, ранее ограниченного с помощью IStream::LockRegion.
-
Извлекает структуру STATSTG для этого потока.
-
Создает новый объект потока с собственным указателем, который ссылается на те же байты, что и исходный поток.
В простом режиме IStream применяются следующие ограничения.
- Поток является простым режимом, если он был создан или открыт из простого хранилища. Хранилище — это простой режим, если он создается или открывается с помощью флага STGM_SIMPLE, заданного в параметре grfMode .
- Методы Clone и CopyTo не поддерживаются.
- Метод Stat поддерживается, но необходимо указать значение STATFLAG_NONAME.
См. также