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, 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 dá suporte. Por exemplo, a interface IStream define fluxos de até 2⁶⁴ bytes de comprimento, exigindo 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 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 em 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 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 a memória global. Na implementação do arquivo composto COM de objetos de fluxo, os recursos de marshaling personalizados no 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 precisar de 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 muito 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 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 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 com antecedência. No entanto, isso não é tão eficiente quanto usar o VirtualAlloc, conforme descrito acima.
Métodos
-
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 de "fim do arquivo" encontrado no sistema de arquivos MS-DOS FAT.)
-
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.
-
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.
-
Altera o tamanho do objeto de fluxo. Nessa implementação, não há garantia de que o espaço alocado será contíguo.
-
Copia um número especificado de bytes do ponteiro de busca atual no fluxo para o ponteiro de busca atual em outro fluxo.
-
A implementação de arquivo composto de 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 liberar todos os buffers de memória para o próximo nível de armazenamento.
Nessa implementação, não importa se você confirma as alterações nos fluxos, você só precisa confirmar as alterações para objetos de armazenamento.
-
Essa implementação não dá suporte a fluxos transacionados, portanto, uma chamada para esse método não tem efeito.
-
O bloqueio de intervalo não é suportado por essa implementação, portanto, uma chamada para esse método não tem efeito.
-
Remove a restrição de acesso em um intervalo de bytes anteriormente restrito com IStream::LockRegion.
-
Recupera a estrutura STATSTG para este fluxo
-
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 é modo simples se foi criado ou aberto a partir de um armazenamento de modo simples. Um armazenamento é 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.
- O método Stat é suportado, mas o valor STATFLAG_NONAME deve ser especificado.
Tópicos relacionados