Partilhar via


IStream - Implementação de arquivos compostos

A interface IStream suporta leitura e gravação de dados para transmitir objetos. Em um objeto de armazenamento estruturado, os objetos de fluxo contêm os dados e os armazenamentos fornecem a estrutura. Dados simples podem ser gravados diretamente em um fluxo, mas, com mais frequência, os fluxos são elementos aninhados em um objeto de armazenamento. Eles são semelhantes aos arquivos padrão.

A especificação de IStream define mais funcionalidade do que a implementação COM suporta. Por exemplo, a interface IStream define fluxos de até 2⁶⁴ bytes de comprimento que exigem um ponteiro de busca de 64 bits. No entanto, a implementação COM suporta apenas fluxos de até 2³² bytes de comprimento (4 GB) e as operações de leitura e gravação são sempre limitadas a 2³² bytes de cada vez. A implementação COM também não suporta transações de fluxo ou bloqueio de região.

Para criar um fluxo simples com base na memória global, obtenha um ponteiro IStreamchamando a função API CreateStreamOnHGlobal. Para obter um ponteiro IStream dentro de um objeto de arquivo composto, chame StgCreateDocfile ou StgOpenStorage. Essas funções recuperam um ponteiroIStorage, com o qual você pode chamar CreateStream ou OpenStream para um ponteiro IStream. Em ambos os casos, o mesmo IStream código de implementação é usado.

Observação

A implementação de arquivo composto de armazenamento estruturado não é bem-sucedida em um método deQueryInterfacepara ISequentialStream, mas inclui os métodos Read e Write por meio do ponteiro de interface IStream.

 

Quando usar

Chame os métodos de IStream para ler e gravar dados em um fluxo.

Como os objetos de fluxo podem ser empacotados para outros processos, os aplicativos podem compartilhar os dados em objetos de armazenamento sem precisar usar memória global. Na implementação de arquivo composto COM de objetos de fluxo, os recursos de empacotamento personalizados em COM criam uma versão remota do objeto original no novo processo quando os dois processos têm acesso à memória compartilhada. Assim, a versão remota não precisa se comunicar com o processo original para realizar suas funções.

A versão remota do objeto de fluxo compartilha o mesmo ponteiro de busca que o fluxo original. Se você não quiser compartilhar o ponteiro de busca, use o método IStream::Clone para fornecer uma cópia do objeto de fluxo para o processo remoto.

Observação

Se estiver criando um objeto de fluxo maior que o heap na memória do computador e você estiver usando um identificador de HGLOBAL de para um objeto de memória global, o objeto de fluxo chamará o métodoGlobalRealloc internamente quando ele exigir mais memória. Como GlobalRealloc sempre copia dados da origem para o destino, aumentar um objeto de fluxo de 20 MB para 25 MB, por exemplo, requer grandes quantidades de tempo. Isso ocorre devido ao tamanho dos incrementos copiados e é agravado se houver menos de 45 MB de memória no computador devido à troca de disco.

A solução preferida é implementar um método IStream que usa memória alocada por VirtualAlloc em vez de GlobalAlloc. Isso pode reservar um grande pedaço de espaço de endereço virtual e, em seguida, confirmar a memória dentro desse espaço de endereço, conforme necessário. Nenhuma cópia de dados ocorre e a memória é confirmada apenas quando é necessária.

Uma alternativa para GlobalRealloc é chamar o método IStream::SetSize no objeto stream para aumentar a alocação de memória antecipadamente. No entanto, isso não é tão eficiente quanto usar VirtualAlloc, conforme descrito acima.

 

Metodologia

ISequentialStream::Leia

Lê um número especificado de bytes do objeto de fluxo na memória a partir do ponteiro de busca atual. Essa implementação retorna S_OK se o final do fluxo foi atingido durante a leitura. (Isso é o mesmo que o comportamento "fim do arquivo" encontrado no sistema de arquivos FAT MS-DOS.)

ISequentialStream::Escrever

Grava um número especificado de bytes no objeto de fluxo a partir do ponteiro de busca atual. Nesta implementação, os objetos de fluxo não são esparsos. Todos os bytes de preenchimento são eventualmente alocados no disco e atribuídos ao fluxo.

IStream::Procure

Altera o ponteiro de busca para um novo local em relação ao início do fluxo, ao final do fluxo ou ao ponteiro de busca atual.

IStream::SetSize

Altera o tamanho do objeto de fluxo. Nesta implementação, não há garantia de que o espaço alocado será contíguo.

IStream::CopyTo

Copia um número especificado de bytes do ponteiro de busca atual no fluxo para o ponteiro de busca atual em outro fluxo.

IStream::Commit

A implementação de arquivo composto do IStream suporta a abertura de fluxos apenas no modo direto, não no modo transacionado. Portanto, o método não tem efeito quando chamado além de liberar todos os buffers de memória para o próximo nível de armazenamento.

Nesta implementação, não importa se você confirma alterações em fluxos, você só precisa confirmar alterações para objetos de armazenamento.

IStream::Reverter

Essa implementação não oferece suporte a fluxos transacionados, portanto, uma chamada para esse método não tem efeito.

IStream::LockRegion

O bloqueio de intervalo não é suportado por essa implementação, portanto, uma chamada para esse método não tem efeito.

IStream::UnlockRegion

Remove a restrição de acesso em um intervalo de bytes anteriormente restrito com IStream::LockRegion.

IStream::Stat

Recupera a estrutura deSTATSTGpara este fluxo

IStream::Clone

Cria um novo objeto de fluxo com seu próprio ponteiro de busca que faz referência aos mesmos bytes que o fluxo original.

Um modo simples IStream está sujeito às seguintes restrições.

  • Um fluxo é um modo simples se tiver sido criado ou aberto a partir de um armazenamento de modo simples. Um armazenamento é um modo simples se for criado ou aberto com o sinalizador de STGM_SIMPLE definido no parâmetro grfMode.
  • Não há suporte para os métodos Clone e CopyTo.
  • O método Stat é suportado, mas o valor STATFLAG_NONAME deve ser especificado.

IStream

IStorage

CreateStreamOnHGlobal

StgCreateDocfile

StgOpenStorage