IStream - Implementazione di file composti

L'interfaccia IStream supporta la lettura e la scrittura di dati in oggetti di flusso. In un oggetto di archiviazione strutturato, gli oggetti flusso contengono i dati e le risorse di archiviazione forniscono la struttura. I dati semplici possono essere scritti direttamente in un flusso, ma più frequentemente i flussi sono elementi annidati all'interno di un oggetto di archiviazione. Sono simili ai file standard.

La specifica di IStream definisce più funzionalità rispetto all'implementazione COM supportata. Ad esempio, l'interfaccia IStream definisce flussi fino a 2⁶⁴ byte di lunghezza che richiedono un puntatore di ricerca a 64 bit. Tuttavia, l'implementazione COM supporta solo flussi fino a 2² byte di lunghezza (4 GB) e le operazioni di lettura e scrittura sono sempre limitate a 2² byte alla volta. L'implementazione COM non supporta anche il blocco delle transazioni di flusso o dell'area.

Per creare un flusso semplice basato sulla memoria globale, ottenere un puntatore IStream chiamando la funzione API CreateStreamOnHGlobal. Per ottenere un puntatore IStream all'interno di un oggetto file composto, chiamare StgCreateDocfile o StgOpenStorage. Queste funzioni recuperano un puntatore IStorage, con cui è possibile chiamare CreateStream o OpenStream per un puntatore IStream. In entrambi i casi viene usato lo stesso codice di implementazione IStream .

Nota

L'implementazione di file composta dell'archiviazione strutturata non riesce in un metodo QueryInterface per ISequentialStream, ma include i metodi Read e Write tramite il puntatore all'interfaccia IStream.

 

Utilizzo

Chiamare i metodi di IStream per leggere e scrivere dati in un flusso.

Poiché è possibile effettuare il marshalling degli oggetti di flusso ad altri processi, le applicazioni possono condividere i dati negli oggetti di archiviazione senza dover usare la memoria globale. Nell'implementazione di file composti COM degli oggetti flusso, le strutture di marshalling personalizzate in COM creano una versione remota dell'oggetto originale nel nuovo processo quando i due processi hanno accesso alla memoria condivisa. Pertanto, la versione remota non deve comunicare con il processo originale per eseguire le sue funzioni.

La versione remota dell'oggetto flusso condivide lo stesso puntatore seek del flusso originale. Se non si vuole condividere il puntatore seek, usare il metodo IStream::Clone per fornire una copia dell'oggetto flusso per il processo remoto.

Nota

Se si crea un oggetto flusso di dimensioni maggiori dell'heap nella memoria del computer e si usa un handle HGLOBAL per un oggetto memoria globale, l'oggetto flusso chiama internamente il metodo GlobalRealloc quando richiede più memoria. Poiché GlobalRealloc copia sempre i dati dall'origine alla destinazione, l'aumento di un oggetto flusso da 20 MB a 25 MB, ad esempio, richiede grandi quantità di tempo. Ciò è dovuto alle dimensioni degli incrementi copiati e peggiora se nel computer sono presenti meno di 45 MB di memoria a causa dello scambio su disco.

La soluzione preferita consiste nell'implementare un metodo IStream che usa la memoria allocata da VirtualAlloc anziché GlobalAlloc. In questo modo è possibile riservare un blocco elevato di spazio indirizzi virtuale e quindi eseguire il commit della memoria all'interno di tale spazio indirizzi in base alle esigenze. Non viene eseguita alcuna copia dei dati e viene eseguito il commit della memoria solo in quanto necessario.

Un'alternativa a GlobalRealloc consiste nel chiamare il metodo IStream::SetSize nell'oggetto flusso per aumentare in anticipo l'allocazione di memoria. Questo non è tuttavia efficiente come l'uso di VirtualAlloc, come descritto in precedenza.

 

Metodi

ISequentialStream::Read

Legge un numero specificato di byte dall'oggetto flusso in memoria a partire dal puntatore di posizionamento corrente. Questa implementazione restituisce S_OK se la fine del flusso è stata raggiunta durante la lettura. Si tratta dello stesso comportamento di "fine del file" trovato nel file system FAT MS-DOS.

ISequentialStream::Write

Scrive un numero specificato di byte nell'oggetto flusso a partire dal puntatore di ricerca corrente. In questa implementazione, gli oggetti flusso non sono di tipo sparse. Eventuali byte di riempimento vengono infine allocati sul disco e assegnati al flusso.

IStream::Seek

Sposta il puntatore di posizionamento su un nuovo percorso relativo all'inizio del flusso, alla fine del flusso o al puntatore di posizionamento corrente.

IStream::SetSize

Modifica le dimensioni dell'oggetto flusso. In questa implementazione non esiste alcuna garanzia che lo spazio allocato sarà contiguo.

IStream::CopyTo

Copia un numero specificato di byte dal puntatore di posizionamento corrente nel flusso al puntatore di posizionamento corrente in un altro flusso.

IStream::Commit

L'implementazione di file composta di IStream supporta l'apertura di flussi solo in modalità diretta, non in modalità transazionata. Pertanto, il metodo non ha alcun effetto quando viene chiamato diverso da per scaricare tutti i buffer di memoria al livello di archiviazione successivo.

In questa implementazione, non importa se si esegue il commit delle modifiche ai flussi, sono necessarie solo le modifiche di commit per gli oggetti di archiviazione.

IStream::Revert

Questa implementazione non supporta i flussi transazionati, pertanto una chiamata a questo metodo non ha alcun effetto.

IStream::LockRegion

Il blocco di intervalli non è supportato da questa implementazione, quindi una chiamata a questo metodo non ha alcun effetto.

IStream::UnlockRegion

Rimuove la restrizione di accesso per un intervallo di byte precedentemente limitato con IStream::LockRegion.

IStream::Stat

Recupera la struttura STATSTG per questo flusso

IStream::Clone

Crea un nuovo oggetto flusso con il proprio puntatore di posizionamento che fa riferimento agli stessi byte del flusso originale.

Un IStream in modalità semplice è soggetto ai vincoli seguenti.

  • Un flusso è in modalità semplice se è stato creato o aperto da una risorsa di archiviazione in modalità semplice. Una risorsa di archiviazione è in modalità semplice se viene creata o aperta con il flag STGM_SIMPLE impostato nel parametro grfMode .
  • I metodi Clone e CopyTo non sono supportati.
  • Il metodo Stat è supportato, ma è necessario specificare il valore STATFLAG_NONAME.

IStream

IStorage

CreateStreamOnHGlobal

StgCreateDocfile

StgOpenStorage