Ler um arquivo.txt e devolver um vetor

Caros amigos,
Sou um iniciante em java e ainda, tenho algumas dúvidas.
Estou com um problema, necessito fazer uma classe que leia um arquivo com um texto em cada linha e preciso apresentar o resultado da leitura em um vetor com as linhas sorteadas ao acaso.
Fiz o código abaixo, porém, está com vários erros. Alguém pode ajudar.

[code]
public class Ler {
private String nome;
private String [] sai;

//Construtor
public String vetor[] (String nomeArquivo){	
	nome = nomeArquivo;
}

File arq = new File(nome);
RandomAccessFile objeto = new RandomAccessFile(arq , "rw");

int i = 0;
String result;
int cont = 0;
while(i < objeto.length()){
	sai [i]= objeto.readLine();
	cont ++;
	if(result==null){
		break ;
	}
	return sai;
	i++;
}	

}[/code]

Que tal dizer os erros?

Aproveita e usa a tag “code” quando for postar código-fonte. Assim você facilita quem está disposto a te ajudar…

Se você não sabe usar a tag code, dá uma lida aqui:
http://www.guj.com.br/posts/list/50115.java
:wink:

[code]import java.io.;
import java.util.
;
import javax.swing.*;

public class Ler {
private String nome;
private String [] sai;

//Construtor
public String vetor[] (String nomeArquivo){	
	nome = nomeArquivo;
}

File arq = new File(nome);
RandomAccessFile objeto = new RandomAccessFile(arq , "rw");

int i = 0;
String result;
int cont = 0;
while(i < objeto.length()){
	sai [i]= objeto.readLine();
	cont ++;
	if(result==null){
		break ;
	}
	return sai;
	i++;
}	

}[/code]

Na linha 10 tem um erro de sintaxe, o meu objetivo é fazer o construtor recebendo o caminho onde se encontra o arquivo a ser lido e devolver um vetor com o arquivo dividido em linhas de Strings.

Na linha 26 apareçe como erro que um método void não pode retornar valor. Acredito que este erro é por estar com o erro de sintaxe na linha 10 e etá sendo interpretado com um metodo void.

os outros dois erros, também devem ser motivados pelo mesmo erro de sintaxe.

Oi Sanches, acabo de postar o código com os erros.

Bom dia OctavianoDiniz,

Dei uma olhada no seu código e tinha alguns erros como: Construtor errado, vetor não inicializado, códigos inacessiveis, etc…
Dei uma corrigida no código e postei aqui embaixo.

espero ter ajudado…
att

import java.io.*;   
import java.util.*;   
import javax.swing.*;   
  
public class Ler {   
    private String nome;   
    private String [] sai; 
    RandomAccessFile objeto;
    
    // O contrutor deve ter o mesmo nome da Classe   
    public Ler(String nomeArquivo){    
        nome = nomeArquivo;   
    }   

    // método que retorna o vetor contendo as informações do arquivo  
    public String[] criarVetor() {
        try {
            File arq = new File(nome);   
            objeto = new RandomAccessFile(arq , "rw");
            sai = new String[(int)objeto.length()]; // inicializa o vetor com o tamanho do arquivo
            for (int i = 0; i < objeto.length(); i++) {
                sai[i]= objeto.readLine();
            }  
            return sai;
        } catch (FileNotFoundException ex) { // trata as exceções do tipo FileNotFoundException 
            ex.printStackTrace();
        } catch (IOException ex) { // trata as exceções do tipo IOException 
            ex.printStackTrace();
        }     
        return null; // só retorna null se der algum erro
    }
    
} 

Oi Bruno,
Agradeço, estou vendo que ainda falta muita coisa para eu aprender, pois cometi erros básicos, vou ter que me esforçar mais para aprender.
Aproveitando a oportunidade será que tens alguma dica de algum livro, apostila ou algum artigo que explique esse início de OO, ou seja de como criar classes e utilizar métodos.
De qualquer forma fico agradeçido pela atenção.
Abraço.

Amigo OctavianoDiniz a correção do seu codigo feita pelo brunolinsalves esta perfeita.
Pra vc rever os erros do teu codigo:
1 - Construtor sempre vai ser com o mesmo nome da Classe
2 - Você utilizou um atributo String result, mas não iniciou, para comparar Strings eh melhor fazer da seguinte forma :

   if(result.equals("")){
      comando
}

3 - “return sai” vc pode utilizar dentro de um metodo que retorna o tipo de “sai” como fez o amigo brunolinsalves que criou um metodo que retorna um Vetor String[]

Flw Precisando de algo!!! eh so chamar!

Olá OctavianoDiniz,

Um bom livro para essa parte é o Java: Como Programar Vol 6 de Deitel. Também já vi várias apostilas boas na net, porém não lembro do endereço de nenhuma. mas da uma olhada em www.apostilando.com

se tiver interesse no livro… segue o link do Livro no Submarino:
http://www.submarino.com.br/books_productdetails.asp?Query=ProductPage&ProdTypeId=1&ProdId=730400&ST=SR

Espero ter ajudado
att

Este Java Como programar do Deitel eu tenho ele… Muito bom o livro!..
:smiley:

Muito bom este fórum, adorei o nível e a presteza nas respostas.
Estou fazendo os ajustes e terminando a minha tarefa, caso necessite de ajuda vou voltar a “postar” aqui.
Valeu.
Abraços

OctavianoDiniz, vc tem o método main? conseguiu incluir os nomes e imprimir o vetor na tela?

usando manipulação de arquivo e array?

Sérgio

Oi Sergio,
Sim eu tenho o método main e o programa rodou, só está havendo um problema, o vetor que estou recebendo não está vindo embaralhado, achava que o RandomAccessFile objeto iria fazer isso.

public class LerArquivo{
	
	public static void main(String[] args) {
		
		String localArq = "E:/Meus Documentos/arquivo.txt";
		
		Ler in = new Ler (localArq );		
		String [] meu = in.criarVetor();		
		
				
		String in = JOptionPane.showInputDialog ("Informe um numero:");
		int num = Integer.parseInt(in);
		String result= "";
		for (int cont = 1; cont <= num; cont ++ ){
			result+= meu[cont]+"\n";
		}
		System.out.println(result);
		
	}
}

Aproveito para fazer outra pergunta. Por que a classe ler não está devolvendo o vetor embaralhado, será que terei de usar outra classe para embaralhar o vetor recebido?

Abraços.

Olá,

O vetor não está sendo devolvido embaralhado pois estamos lendo o arquivo e preenchendo o array simultaneamente. Porém podemos embaralhar o vetor apenas criando outro método chamado embaralhaVetor() na classe Ler.
Segue abaixo o código da classe com o método embaralharVetor()
Note que na linha 25, chamamos o método embaralhaVetor() e por isso, o vetor será devolvido embaralhado.

att

import java.io.*;     
import java.util.*;     
import javax.swing.*;     
     
public class Ler {     
    private String nome;     
    private String [] sai;   
    RandomAccessFile objeto;   
       
    // O contrutor deve ter o mesmo nome da Classe     
    public Ler(String nomeArquivo){       
        nome = nomeArquivo;     
    }     
  
    // método que retorna o vetor contendo as informações do arquivo     
    public String[] criarVetor() {   
        try {   
            File arq = new File(nome);     
            objeto = new RandomAccessFile(arq , "rw");   
            sai = new String[(int)objeto.length()]; // inicializa o vetor com o tamanho do arquivo   
            for (int i = 0; i < objeto.length(); i++) {   
                sai[i]= objeto.readLine();   
            }
            // Chama o método para embaralhar o vetor
            embaralhaVetor();
            return sai;   
        } catch (FileNotFoundException ex) { // trata as exceções do tipo FileNotFoundException   
            ex.printStackTrace();   
        } catch (IOException ex) { // trata as exceções do tipo IOException   
            ex.printStackTrace();   
        }       
        return null; // só retorna null se der algum erro   
    }   
    
    public void embaralhaVetor() {
    	// Classe geradora de números aleatórios
    	Random random = new Random();
    	int j;
    	for (int i = 0; i < sai.length; i++) {
    		 // Gera um número aleatório de 0 a sai.length-1 
    		 j = random.nextInt(sai.length);
    		 // Troca o conteudo de sai[i] com sai[j]
    		 String temp = sai[i];
    		 sai[i] = sai[j];
    		 sai[j] = temp;
    	}
    }
} 

Oi Bruno,
O novo método embaralhaVetor apresenta um erro, ele não pode transformar um int em um String.
Acredito que o método embarahar trabalha com os índices do vetor, então não vai apresentar o vetor lido embaralhado.
Outra coisa, também não está garantindo que não haja repetição.
Qual seria o modo de eu conseguir receber o vetor lido já embaralhado quando eu informo o local do arquivo?

Bom dia OctavianoDiniz,

Fiz a seguinte alteração no método embaralhaVetor() para corrigir o erro que estava dando…

 public void embaralhaVetor() {
    	// Classe geradora de números aleatórios
    	Random random = new Random();
    	int j;
    	for (int i = 0; i < sai.length; i++) {
    		 // Gera um número aleatório de 0 a sai.length-1 
    		 j = random.nextInt(sai.length);
    		 // Troca o conteudo de sai[i] com sai[j]
    		 String temp = sai[i];
    		 sai[i] = sai[j];
    		 sai[j] = temp;
    	}
    }

Aqui eu testei, e o vetor está sendo devolvido embaralhado.
você falou: , Outra coisa, também não está garantindo que não haja repetição.
você quer q não exista repetição dentro do array ?

att

Estou pensando em uma classe mais genérica, por exemplo embaralhar cartas, neste caso não poderá ter carta repetida.
Uma classe que embaralhe um vetor recebido e, devolve o vetor completo, mas todo fora da ordem original.

Caros amigos,
Continuo com problema para fazer o programa. É um gerador de Lero-Lero bem mais simples do que o original, tenho uma classe que lê um arquivo e devolve um vetor, mas estão ocorrendo erros.
Vamos por parte.

Segue a classe que lê um arquivo e devolve um vetor com uma linha em cada posição.

[code]

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Random;
import java.util.Scanner;

public class TesteLeArq {
private String nomeArquivo;
private String [] result;
private int numLinha = 0;

public TesteLeArq ( ){		
}	

// método que retorna o vetor contendo as informações do arquivo     
           public String[] criarVetor(String nomeArquivo) {
          try {   
 	//Aqui faço a leitura do arquivo para mostrar a quantidade de linhas, ou seja, para eu saber o tamanho do vetor devolvido
    	Scanner arquivo = new Scanner (new File (this.nomeArquivo));        	
    	while (arquivo.hasNextLine()){
    		String linha = arquivo.nextLine();
    		numLinha ++;
    	}
            //Agora faço uma nova leitura do arquivo para retornar o vetor
    	arquivo = new Scanner (new File (this.nomeArquivo));        	       
            for (int cont = 0; cont < numLinha; cont++) {
        	      String linha = arquivo.nextLine();
        	       result[cont]= linha ;              	
            }             
             return result;   
           } catch (FileNotFoundException ex) { // trata as exceções do tipo FileNotFoundException   
               ex.printStackTrace();   
           }    
           return null; // só retorna null se der algum erro   	
    }  

    //Pretendia fazer um método que embaralhasse todo o vetor de saída sem haver repetiçao
    // a idéia era de apresentar um vetor de int com as posições embaralhadas. Não sei se é possível.
    //Este método foi cópia do recebido aqui.
    public void embaralhaVetor() {   
    // Classe geradora de números aleatórios   
    Random random = new Random();   
    int j;   
    for (int i = 0; i < result.length; i++) {   
         // Gera um número aleatório de 0 a result.length-1   
         j = random.nextInt(result.length);   
         // Troca o conteudo de sai[i] com sai[j]   
         String temp = result[i];   
         result[i] = result[j];   
         result[j] = temp;   
    }   
  }

//Método para retornar o número de linhas do arquivo lido, ou seja o tamanho do vetor.
public int numLinhasArquivo (){
	return numLinha;	
}

} [/code]

Segue agora o programa

[code]

import javax.swing.JOptionPane;

public class Prog {

   public static void main(String[] args) {
	
            //Crio uma String para armazenar o caminho do arquivo.
String localArq ="arquivo.txt";			

//crio o objeto TesteLeArq enviando a String com o endereco do arquivo
TesteLeArq objeto = new TesteLeArq ();		
String [] dados = new String [objeto.numLinhasArquivo()];	
int linhas = objeto.numLinhasArquivo();

             /******************
             * O ERRO ESTÁ AQUI *
             *******************/
            //aqui faço um teste para ver o número de linhas e é impresso 0, apesar de ter 123 linhas.	
System.out.println ("O número de linhas é:  "+objeto.numLinhasArquivo());
			
		
	
String in = JOptionPane.showInputDialog ("Informe o numero de frases:");
int numFrases = Integer.parseInt(in);
String frase = "";	
	
for (int cont = 1; cont <= numFrases; cont ++ ){
	frase += (objeto [(1+(int)(Math.random()*( linhas - 1 )))] \n");
	}

             //Aqui necessito passar a primeira letra do String para MAIÚSCULA, mas não estou conseguindo. Por favor ajude	
for (int cont = 1; cont <= numFrases; cont ++ ){
                 frase += (Character.toUpperCase(objeto [(1+(int)(Math.random()*(linhas -1)))].charAt(0)).substring(1)\n");
	}		
	System.out.println(frase);		
}

}[/code]

Por favor ajudem.

Olá OctavianoDiniz,

Acho que descobri o motivo do erro.
Dê uma olhada nesse seguinte trecho de código:

    //crio o objeto TesteLeArq enviando a String com o endereco do arquivo   
    TesteLeArq objeto = new TesteLeArq ();         
    String [] dados = new String [objeto.numLinhasArquivo()];     
    int linhas = objeto.numLinhasArquivo();  

Nesse trecho, você cria o objeto TesteLeArq enviando a String com o endereço do arquivo. Porém, você não chama o método criarVetor. Portanto, o array result ainda não foi instanciado.

Para resolver esse erro, basta inserir uma chamada ao método criarVetor. Segue o exemplo do código que resolve esse problema:

    //crio o objeto TesteLeArq enviando a String com o endereco do arquivo   
    TesteLeArq objeto = new TesteLeArq (); 
    objeto.criarVetor(this.nomeArquivo);        
    String [] dados = new String [objeto.numLinhasArquivo()];     
    int linhas = objeto.numLinhasArquivo();  

quanto à sua outra dúvida:

//Pretendia fazer um método que embaralhasse todo o vetor de saída sem haver repetiçao   

Não entendi muito bem isso. Porque você deseja evitar a repetição ?
você não poderia fazer isso na hora que você está preenchendo o vetor ?

Espero ter ajudado
att

Oi brunolinsalves,
Peço desculpas por não ter respondido ao amigo, pois estive envolvido com um problema grave de saúde do meu sogro e não consegui navegar na internet, mas agora as coisas melhoraram e estou de volta.

brunolinsalves o problema não foi resolvido com a tua solução e resolvi refazer o problema e acredito que agora ficou melhor, mas, apareceu um probleminha, que acredito ser de melhor solução.

É que o novo programa que fiz ao acessar os dados da classe não está zerando o número de linhas do arquivo e, ainda, não descobri o erro, será que pode ajudar.

Aqui vai a classe que fiz.

[code]
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class LerArquivo {
private String endereco;
private String [] result;
private static int numLin;

//Construtor
public LerArquivo (String enderecoArquivo){
	endereco = enderecoArquivo;
	//result = null;
}	
//Metodo para saber o numero de linhas do arquivo
public int numLinhasArquivo() {//Acho que aqui está faltando algo para que, ao ler um novo arquivo, o retorno seja reiniciado com zero
	try {		
		Scanner arq = new Scanner (new File (endereco));	      
        while (arq.hasNextLine()){
        	arq.nextLine();
        	numLin ++;
        }
	}catch (FileNotFoundException e) { // trata as exceções do tipo FileNotFoundException   
        e.printStackTrace();   
    }
	return numLin;
}
// método que retorna o vetor contendo as informações do arquivo     
public String[] criarVetor() {   
    try {   
    	Scanner arq = new Scanner (new File (endereco));
    	int cont = 0;
    	result = new String [numLin];
    	while (arq.hasNextLine()){
    		String linha = arq.nextLine();
    		result [cont] = linha;  
    		cont ++;
    	}
    	return result;        
      
    } catch (FileNotFoundException ex) { // trata as exceções do tipo FileNotFoundException   
        ex.printStackTrace();   
   } 
        return result; 
}   

}[/code]

Aqui segue o programa

[code]
import javax.swing.JOptionPane;
import LeroLero.LeArqDevolVetor;

public class Programa {

public static void main(String[] args) {
	LerArquivo artSub = new LerArquivo("E:/ArtigoComSubstantivo.txt");
	int linArtSub = artSub.numLinhasArquivo();
	
	LerArquivo prep = new LerArquivo("E:/Preposicao.txt");
	int linPrep = prep.numLinhasArquivo();
	
	LerArquivo verb = new LerArquivo("E:/Verbos.txt");	
	int linVerbo = verb.numLinhasArquivo();
	
	String [] artSubs = new String [linArtSub];
		artSubs = artSub.criarVetor();		
	String [] preposicao = new String [linPrep];
		preposicao = prep.criarVetor();			
	String [] verbo = new String [linVerbo];
		verbo = verb.criarVetor();
		
                                            //Aqui estou fazendo um teste para saber os valores que as variáveis de número de linhas 
                                            //de cada arquivo tem e são mostrados os valores incrementados, ou seja, a segunda é a
                                            //soma da primeira com a segunda e a terceira a soma das anteriores. 
		System.out.println("linArtSub "+linArtSub);
		System.out.println("linPrep "+linPrep);
		System.out.println("linVerbo "+linVerbo);
		System.out.println("artSubs "+artSubs);
					
	
	String in = JOptionPane.showInputDialog ("Informe o numero de frases:");
	int numFrases = Integer.parseInt(in);
	String frase = "";	
	
	for (int cont = 1; cont <= numFrases; cont ++ ){
		frase += (artSubs [(1+(int)(Math.random()*(linArtSub -1)))]
		+" "+verbo [(1+(int) (Math.random()*(linVerbo -1)))]
		+" "+preposicao [(1+(int) (Math.random()*(linPrep-1)))]
		+artSubs [(1+(int) (Math.random()*(linArtSub-1)))]+".\n");
	}		
			
	System.out.println(frase);			
}

}[/code]