Compartilhar via


IStream - Implementação de arquivo composto

A interface IStream oferece suporte à leitura e gravação de dados em objetos de fluxo. 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, fluxos são elementos aninhados em um objeto de armazenamento. Eles são semelhantes aos arquivos padrão.

A especificação do 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 por vez. A implementação COM também não oferece suporte a transações de fluxo ou bloqueio de região.

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

Observação

A implementação de arquivo composto de armazenamento estruturado não é bem-sucedida em um método QueryInterface para 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 HGLOBAL para um objeto de memória global, o objeto de fluxo chamará o método GlobalRealloc internamente quando ele exigir mais memória. Como o 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 se deve 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 uma grande parte do 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ário.

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

 

Métodos

ISequentialStream::Leitura

Lê um número especificado de bytes do objeto de fluxo para a 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 MS-DOS FAT.)

ISequentialStream::Gravação

Grava um número especificado de bytes no objeto de fluxo começando no ponteiro de busca atual. Nessa 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::Buscar

Altera o ponteiro de busca para um novo local relativo ao início do fluxo, ao fim do fluxo ou ao ponteiro de busca atual.

IStream::SetSize

Altera o tamanho do objeto de fluxo. Nessa 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::Confirmar

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

Nessa 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::Região de bloqueio

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

IStream::Região de Desbloqueio

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

IStream::Estat

Recupera a estrutura STATSTG para este fluxo

IStream::Clone

Cria um novo objeto de fluxo com seu próprio ponteiro de busca que referencia os mesmos bytes como o fluxo original.

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

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

IStream

IStorage

CreateStreamOnHGlobal

StgCreateDocfile

StgOpenStorage