Translate

Mostrando postagens com marcador Random Access File. Mostrar todas as postagens
Mostrando postagens com marcador Random Access File. Mostrar todas as postagens

sábado, 17 de dezembro de 2011

Java NIO - Acesso randômico a arquivo

O Java NIO é uma das melhorias mais significantes para manipulação de I/O. A sigla NIO é de New I/O, ou seja, renovação do pacote java.io.* em relação ao acesso a recursos de memórias externas como um arquivo ou um cliente remoto (host). O pacote NIO está aninhado em java.nio.*.

Nota: I/O é o termo utilizado para denominar a troca de dados de uma área para outra em computação. Esta operação pode ser a comunicação ministrada por uma CPU para transitar dados da sua RAM para um HD, CD R/W, DVD R/W, pasta de rede, um PenDrive (flash), outro computador ou banco de dados. Numa linguagem de programação, este acesso é classificado de alto risco, pois quando os dados saem ou chegam de um recurso externo, muitas coisas podem ocorrer como o desligamento deste recurso, queda do meio físico da comunicação, falha no sistema lógico etc.

Durante minha experiência com Java NIO, me despertou atenção a sua capacidade de acesso não bloqueante. Isso mesmo, você escreve os dados em um recurso I/O como é um arquivo e pode programar para o gerenciador da escrita não deixar em espera sua linha de execução (thread). A mesma espera não é necessária se os dados enviados pelo recurso ainda não estiverem prontos.

O acesso não bloqueante torna possível a terceirização do controle de múltiplos I/O para o Java NIO sem requerer de você a criação de múltiplas threads (linhas de execução paralelas) para gerenciar este acesso. Entretanto, esta terceirização requer cuidados e domínio do tipo de recurso I/O referentes as cerimônias para abertura da comunicação, transferência de dados e encerramento da comunicação. O Java NIO não abstrai estes controles e caberá a você entender bem como funciona o tipo de recurso a operar.

Segue um exemplo de acesso randômico a arquivo para escrita (criação automática quando não existe) e posterior leitura. É necessário ter uma pasta "c:\temp" em seu PC ou mude este caminho no código:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;


public class TesteFileChannel {


    public static void main(String[] args) {

        TesteFileChannel tfc = new TesteFileChannel();
       
        tfc.writeText();
       
        tfc.readText();
       
       
    }
   
    public void writeText() {

        String text = null;
        FileChannel rwChannel = null;
        MappedByteBuffer rwBuffer = null;

        try {

            // Texto para guardar
            text = "Olá mundo";

            // Abre canal de comunicação
            rwChannel = new RandomAccessFile("c:/temp/datafile.txt", "rw").getChannel();

            // Aloca uma fatia bytes para guardar o texto a partir do canal do arquivo
            rwBuffer = rwChannel.map(FileChannel.MapMode.READ_WRITE, 0, text.length());

            // Coloca o ponteiro na posição ZERO da memória mapeada
            rwBuffer.position(0);

            // Escreve os bytes do texto no arquivo
            rwBuffer.put(text.getBytes(), 0, text.getBytes().length);

            // Como o acesso é não bloqueante, neste caso é forçada
            // a efetivação escrita caso esteja pendente
            rwChannel.force(true);

            // Encerra canal de comunicação
            rwChannel.close();

            // Destrói o objeto representante da memória alocada 
            rwBuffer.clear();

            System.out.println("Concluída a escrita com sucesso: " + text);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void readText() {

        byte[] bytes = null;
        String text = null;
        FileChannel rwChannel = null;
        MappedByteBuffer rwBuffer = null;

        try {

            // Abre canal de comunicação
            rwChannel = new RandomAccessFile("c:/temp/datafile.txt", "rw").getChannel();

            // Aloca uma fatia bytes para guardar o texto a partir do canal do arquivo
            rwBuffer = rwChannel.map(FileChannel.MapMode.READ_WRITE, 0, rwChannel.size());

            // Coloca o ponteiro na posição ZERO da memória mapeada
            rwBuffer.position(0);

            // Vetor para leitura
            bytes = new byte[(int) rwChannel.size()];

            // Lê os bytes do texto no arquivo
            rwBuffer.get(bytes, 0, bytes.length);

            // Converte bytes para texto
            text = new String(bytes);

            // Encerra canal de comunicação
            rwChannel.close();

            // Destrói o objeto representante da memória alocada 
            rwBuffer.clear();

            System.out.println("Concluída a leitura com sucesso: " + text);
           

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}