• Nenhum resultado encontrado

As bibliotecas Java para I/O (java.io e java.nio) oferecem numerosas classes de stream. Mas todas as classes de stream de entrada são subclasses da classe abstrata InputStream, e todas as classes stream de saída são subclasses da classe abstrata OutputStream. A figura abaixo ilustra a hierarquia de classes do pacote java.io.

Figura 20 – Biblioteca Java IO.

O recurso de serialização permite que um objeto seja transformado em um stream de bytes, que podem ser armazenados em um arquivo e enviados via rede. Através desses bytes torna-se possível recriar a classe serializada, desde que esta implemente a interface Serializable ou a Externalizable.

Somente objetos que implementem essas interface podem ser “desintegrados” em bytes, ou “integrados” a partir dos bytes. A interface Externalizable, por exemplo, deve implementar os métodos writeExternal e readExternal. As variáveis serão salvas ou lidas por esses métodos. Essas duas chamadas recebem uma classe do tipo ObjectOutput e ObjectInput, respectivamente. O principal método da classe ObjectOutput é writeObject e o da classe ObjectInput é o readObject.

Uma vez aberta a stream, é retornado um ponteiro para a estrutura FILE. Este ponteiro FILE – algumas vezes chamado de ponteiro stream ou stream – é usado para fazer referência ao arquivo para todas as entradas/saídas subsequentes.

Todas as funções de I/O stream fornecem entrada e saída bufferizada, formatada ou não formatada. Uma stream bufferizada proporciona uma localização de armazenamento intermediária para todas as informações que são provenientes de stream e toda saída que está sendo enviada a stream. I/O em disco é uma operação que toma tempo, mas a bufferização da stream agilizará sua aplicação. Ao invés de introduzir os dados stream, um caractere ou uma estrutura a cada vez, as funções I/O stream acessam os dados em um bloco de cada vez.

À medida que a aplicação necessita processar a entrada, ela simplesmente acessa o buffer, o que é um processo muito mais rápido. Quando o buffer estiver vazio, será acessado um novo bloco de disco. O inverso também é verdadeiro para saída stream. Ao invés de colocar fisicamente na saída todos os dados, à medida que é executada a instrução de saída, as funções de I/O stream colocam todos os dados de saída no buffer. Quando o buffer estiver cheio, os dados serão escritos no disco.

Dependendo da linguagem de alto nível que estiver sendo utilizada, pode ocorrer um problema de I/O bufferizado. Por exemplo, se o programa executar várias instruções de saída que não preencham o buffer de saída, condição necessária para que ele fosse descarregado no disco, aquelas informações serão perdidas quando terminar o processamento de programa.

A solução geralmente envolve a chamada de uma função apropriada para “limpar” o buffer. É claro que uma aplicação bem escrita não deverá ficar dependendo destes recursos automáticos, mas deverá sempre detalhar explicitamente cada ação que o programa deve tomar. Mais uma observação: se a aplicação terminar de maneira anormal quando se estiver usando stream I/O, os buffers de saída podem não ser esgotados (limpos), resultando em perda de dados.

O último tipo de entrada e saída é chamado “low-level I/O” – I/O de baixo nível. Nenhuma das funções de I/O de baixo nível executa bufferização e formatação. Ao invés disso, elas chamam diretamente os recursos de I/O do sistema operacional. Estas rotinas permitem acessar arquivos e dispositivos periféricos em um nível mais básico do que as funções stream.

Os arquivos abertos desta maneira retornam um manipulador de arquivo, um valor inteiro que é utilizado para fazer referência ao arquivo em operações subseqüentes. Em geral, é uma prática ruim de programação misturar funções de I/O stream com rotinas de baixo nível.

Como as funções stream são bufferizadas e as funções de baixo nível não, a tentativa de acessar o mesmo arquivo ou dispositivo por dois métodos diferentes leva à confusão e à eventual perda de dados nos buffers.

5.1 Stream em Java

As bibliotecas Java para I/O (java.io e java.nio) oferecem numerosas classes de stream. Mas todas as classes de stream de entrada são subclasses da classe abstrata InputStream, e todas as classes stream de saída são subclasses da classe abstrata OutputStream. A figura abaixo ilustra a hierarquia de classes do pacote java.io.

Figura 20 – Biblioteca Java IO.

O recurso de serialização permite que um objeto seja transformado em um stream de bytes, que podem ser armazenados em um arquivo e enviados via rede. Através desses bytes torna-se possível recriar a classe serializada, desde que esta implemente a interface Serializable ou a Externalizable.

Somente objetos que implementem essas interface podem ser “desintegrados” em bytes, ou “integrados” a partir dos bytes. A interface Externalizable, por exemplo, deve implementar os métodos writeExternal e readExternal. As variáveis serão salvas ou lidas por esses métodos. Essas duas chamadas recebem uma classe do tipo ObjectOutput e ObjectInput, respectivamente. O principal método da classe ObjectOutput é writeObject e o da classe ObjectInput é o readObject.

Esses métodos serão os responsáveis pela transformação da classe em bytes e vice- versa. Existem classes concretas para essas interfaces, que são ObjectOutputStream e ObjectInputStream. Este recurso, serialização, pode ser utilizado em aplicações visuais, por exemplo, para permitir que os usuários salvem seus trabalhos em um arquivo. Neste caso, antes de escrever um objeto em uma stream, os objetos deverão ser serializados.

Deve-se considerar a serialização de objetos semelhante à divisão de um objeto em pequenos pedaços para poder escrevê-los em uma stream de bytes. O termo para este processo é serialização de objetos.

No documento Java Interfaces Gráficas e Banco de Dados (páginas 52-54)

Documentos relacionados