Pelo estudo anterior, sabemos que se você for ler um arquivo, precisará criar um fluxo de entrada apontando para o arquivo; se for escrever um arquivo, precisará criar um fluxo de saída apontando para o arquivo. Então, você pode criar um fluxo através do qual possa ler e gravar arquivos? É exatamente disso que trata esta seção sobre fluxos aleatórios.
O fluxo criado pela classe RandomAccessFile é chamado de fluxo aleatório . Ao contrário dos fluxos de entrada e saída anteriores, a classe RandomAccessFile não é uma subclasse da classe InputStream nem uma subclasse da classe OutputStream. Porém, o ponto do fluxo criado pela classe RandomAccessFile pode ser usado como origem do fluxo ou como destino do fluxo. Em outras palavras, ao se preparar para ler e gravar um arquivo, crie um fluxo aleatório apontando para o. arquivo, para que você possa ler dados do arquivo desse fluxo e também gravar dados no arquivo por meio desse fluxo.
A seguir estão os dois construtores da classe RandomAccessFile:
O parâmetro name é usado para determinar um nome de arquivo, fornecendo a origem do fluxo criado, que também é o destino do fluxo. O parâmetro mode é r (somente leitura) ou rw (leitura-gravação), que determina os direitos de acesso do fluxo criado ao arquivo.
O arquivo de parâmetro é um objeto File que fornece a origem do fluxo criado e também é o destino do fluxo. O parâmetro mode é r (somente leitura) ou rw (leitura-gravação), que determina os direitos de acesso do fluxo criado ao arquivo.
Nota : Quando o fluxo RandomAccessFile aponta para um arquivo, o arquivo não é atualizado.
Existe um método seek(long a) na classe RandomAccessFile que é usado para localizar a posição de leitura e gravação do fluxo RandomAccessFile. O parâmetro a determina o número de bytes da posição de leitura e gravação até o início do arquivo. Além disso, o fluxo também pode chamar o método getFilePointer() para obter a posição atual de leitura e gravação do fluxo. O fluxo RandomAccessFile é mais flexível para leitura e gravação de arquivos do que leitura e gravação sequencial.
Por exemplo, escreva vários inteiros int em um arquivo chamado tom.dat e depois leia os dados na ordem inversa:
importjava.io.*;publicclassMain{publicstaticvoidmain(Stringargs[]){RandomAccessFileinAndOut=null;intdata[]={1,2,3,4,5,6,7,8,9,10};try{inAndOut=newRandomAccessFile (tom.dat,rw);for(inti=0;i<data.length;i++){inAndOut.writeInt(data[i]);}for(longi=data.length-1;i>=0;i --){inAndOut.seek(i*4);System.out.printf(t%d,inAndOut.readInt());/*Um dado do tipo int ocupa 4 bytes, inAndOut começa a partir do 36º do arquivo Read os últimos bytes inteiros e lê um inteiro a cada 4 bytes para frente*/}inAndOut.close();}catch(IOExceptione){}}}
Os métodos comuns do fluxo RandomAccessFile são os seguintes:
Nota : Quando o método readLine() do fluxo RandomAccessFile lê arquivos contendo caracteres não ASCⅡ, como arquivos contendo caracteres chineses, "caracteres distorcidos" aparecerão. Portanto, é necessário recodificar a string lida por readLine() usando a codificação "iso-8859-1" e armazená-la em uma matriz de bytes e, em seguida, usar a codificação padrão da máquina atual para converter a matriz em uma string . A operação é a seguinte:
Stringstr=in.readLine();
byteb[]=str.getBytes(iso-8859-1);
Stringcontent=newString(b);
Se a codificação padrão da máquina for "GB2312", então
Stringcontent=newString(b);
Equivalente a
Stringcontent=newString(b,GB2312);
Por exemplo:
importjava.io.*;publicclassMain{publicstaticvoidmain(Stringargs[]){RandomAccessFilein=null;try{in=newRandomAccessFile(Main.java,rw);longlength=in.length();//Obter o comprimento do arquivo longposition= 0; in.seek(position);//Localiza a posição de leitura no início do arquivo while(position<length){Stringstr=in.readLine();byteb[]=str.getBytes(iso-8859-1) ;str =newString(b);posição=in.getFilePointer();System.out.println(str);}}catch(IOExceptione){}}}