IStream: implementación de archivos compuestos
La interfaz IStream admite la lectura y escritura de datos para transmitir objetos. En un objeto de almacenamiento estructurado, los objetos stream contienen los datos y los almacenamientos proporcionan la estructura . Los datos simples se pueden escribir directamente en una secuencia, pero con más frecuencia, los flujos son elementos anidados dentro de un objeto de almacenamiento. Son similares a los archivos estándar.
La especificación de IStream define más funcionalidad que la que admite la implementación COM. Por ejemplo, la interfaz IStream define secuencias de hasta 2⁶⁴ bytes de longitud que requieren un puntero de búsqueda de 64 bits. Sin embargo, la implementación COM solo admite secuencias de hasta 2³² bytes de longitud (4 GB) y las operaciones de lectura y escritura siempre se limitan a 2³² bytes a la vez. La implementación com tampoco admite el bloqueo de regiones o transacciones de flujos.
Para crear una secuencia sencilla basada en la memoria global, obtenga un puntero IStream llamando a la función de API CreateStreamOnHGlobal. Para obtener un puntero IStream dentro de un objeto de archivo compuesto, llame a StgCreateDocfile o StgOpenStorage. Estas funciones recuperan un puntero IStorage, con el que puede llamar a CreateStream o OpenStream para un puntero IStream. En cualquier caso, se usa el mismo código de implementación de IStream .
Nota:
La implementación de archivos compuestos del almacenamiento estructurado no se realiza correctamente en un método QueryInterface para ISequentialStream, pero incluye los métodos Read y Write a través del puntero de interfaz IStream.
Cuándo usar
Llame a los métodos de IStream para leer y escribir datos en una secuencia.
Dado que los objetos de secuencia se pueden serializar en otros procesos, las aplicaciones pueden compartir los datos en objetos de almacenamiento sin tener que usar memoria global. En la implementación de archivos compuestos COM de objetos de flujo, las instalaciones de serialización personalizadas en COM crean una versión remota del objeto original en el nuevo proceso cuando los dos procesos tienen acceso a memoria compartida. Por lo tanto, la versión remota no necesita comunicarse con el proceso original para llevar a cabo sus funciones.
La versión remota del objeto de secuencia comparte el mismo puntero de búsqueda que la secuencia original. Si no desea compartir el puntero de búsqueda, use el método IStream::Clone para proporcionar una copia del objeto de secuencia para el proceso remoto.
Nota:
Si crea un objeto de secuencia mayor que el montón en la memoria del equipo y usa un identificador HGLOBAL para un objeto de memoria global, el objeto stream llama al método GlobalRealloc internamente cuando requiere más memoria. Dado que GlobalRealloc siempre copia datos del origen al destino, aumentar un objeto de flujo de 20 MB a 25 MB, por ejemplo, requiere grandes cantidades de tiempo. Esto se debe al tamaño de los incrementos copiados y se empeora si hay menos de 45 MB de memoria en el equipo debido al intercambio de disco.
La solución preferida es implementar un método IStream que usa la memoria asignada por VirtualAlloc en lugar de GlobalAlloc. Esto puede reservar un gran fragmento de espacio de direcciones virtuales y, a continuación, confirmar la memoria dentro de ese espacio de direcciones según sea necesario. No se produce ninguna copia de datos y solo se confirma la memoria, ya que es necesaria.
Una alternativa a GlobalRealloc es llamar al método IStream::SetSize en el objeto de secuencia para aumentar la asignación de memoria de antemano. Sin embargo, esto no es tan eficaz como usar VirtualAlloc, como se ha descrito anteriormente.
Métodos
-
Lee un número especificado de bytes del objeto de flujo en la memoria, empezando en el puntero de búsqueda actual. Esta implementación devuelve S_OK si se alcanzó el final de la secuencia durante la lectura. (Este es el mismo que el comportamiento del "final del archivo" que se encuentra en el sistema de archivos MS-DOS FAT).
-
Escribe un número especificado de bytes en el objeto de secuencia a partir del puntero de búsqueda actual. En esta implementación, los objetos de secuencia no son dispersos. Los bytes de relleno se asignan finalmente en el disco y se asignan a la secuencia.
-
Cambia el puntero de búsqueda a una nueva ubicación respecto al principio del flujo, al final del flujo o al puntero de búsqueda actual.
-
Cambia el tamaño del objeto de secuencia. En esta implementación, no hay ninguna garantía de que el espacio asignado sea contiguo.
-
Copia un número especificado de bytes del puntero de búsqueda actual del flujo en el puntero de búsqueda actual de otro flujo.
-
La implementación de archivo compuesto de IStream solo admite la apertura de secuencias en modo directo, no en modo transaccionado. Por lo tanto, el método no tiene ningún efecto cuando se llama a distinto de vaciar todos los búferes de memoria al siguiente nivel de almacenamiento.
En esta implementación, no importa si confirma cambios en secuencias, solo necesita confirmar los cambios para los objetos de almacenamiento.
-
Esta implementación no admite flujos transaccionados, por lo que una llamada a este método no tiene ningún efecto.
-
Esta implementación no admite el bloqueo de intervalo, por lo que una llamada a este método no tiene ningún efecto.
-
Quita la restricción de acceso en un intervalo de bytes previamente restringido con IStream::LockRegion.
-
Recupera la estructura STATSTG de esta secuencia.
-
Crea un nuevo objeto de flujo con su propio puntero de búsqueda que hace referencia a los mismos bytes que el flujo original.
Un IStream en modo simple está sujeto a las siguientes restricciones.
- Una secuencia es un modo simple si se creó o abrió desde un almacenamiento en modo simple. Un almacenamiento es modo simple si se crea o se abre con la marca STGM_SIMPLE establecida en el parámetro grfMode .
- No se admiten los métodos Clone y CopyTo.
- Se admite el método Stat , pero se debe especificar el valor STATFLAG_NONAME.
Temas relacionados