IStream – Implementação de arquivo composto

A interface IStream dá 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 dá suporte. 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 dá suporte apenas a fluxos de até 2 gb² bytes de comprimento (4 GB) e as operações de leitura e gravação são sempre limitadas a 2 gb² bytes por vez. A implementação COM também não dá 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 do 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 da interface IStream .

 

Quando usar

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

Como os objetos de fluxo podem ter marshaling em outros processos, os aplicativos podem compartilhar os dados em objetos de armazenamento sem precisar usar a memória global. Na implementação de arquivo composto COM de objetos de fluxo, as instalações de marshaling personalizadas no COM criam uma versão remota do objeto original no novo processo quando os dois processos têm acesso à memória compartilhada. Portanto, a versão remota não precisa se comunicar com o processo original para executar 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 seek, 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 e 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 ocorre devido ao tamanho dos incrementos copiados e piora se houver menos de 45 MB de memória no computador devido à troca de disco.

A solução preferencial é 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 somente conforme necessário.

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

 

Métodos

ISequentialStream::Read

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 retornará S_OK se o final do fluxo tiver sido atingido durante a leitura. (Isso é o mesmo que o comportamento de "fim do arquivo" encontrado no sistema de arquivos FAT do MS-DOS.)

ISequentialStream::Write

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::Seek

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á nenhuma 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 dá suporte à abertura de fluxos somente no modo direto, não no modo transacionado. Portanto, o método não tem efeito quando chamado além de para liberar todos os buffers de memória para o próximo nível de armazenamento.

Nessa implementação, não importa se você confirmar alterações em fluxos, só precisará confirmar alterações para objetos de armazenamento.

IStream::Revert

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

IStream::LockRegion

O bloqueio de intervalo não é compatível com 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 restritos com IStream::LockRegion.

IStream::Stat

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 restrições a seguir.

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

Istream

IStorage

Createstreamonhglobal

Stgcreatedocfile

Stgopenstorage