DevMedia
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
post favorito     comentários

Aprenda a utilizar o Scanner

Aprenda neste artigo como utilizar o Scanner. Uma nova classe, adicionada ao J2SE 5.0.

[fechar]

Você não gostou da qualidade deste conteúdo?

(opcional) Você poderia comentar o que não lhe agradou?

Confirmo meu voto negativo

J2SE 5.0 adiciona classes e métodos que podem facilitar a execução de algumas tarefas. Nesta dica você verá como a classe java.util.Scanner recentemente adicionado faz a leitura e a análise gramatical em strings e tipos primitivos utilizando expressões regulares.

Antes da liberação do J2SE 5.0, você escreveu código provavelmente como a classe TextReader para ler textos de um arquivo:

   import java.io.BufferedReader;
   import java.io.FileReader;
   import java.io.IOException;
   import java.io.File;

   public class TextReader {
     private static void readFile(String fileName) {
       try {
         File file = new File(fileName);
         FileReader reader = new FileReader(file);
         BufferedReader in = new BufferedReader(reader);
         String string;
         while ((string = in.readLine()) != null) {
           System.out.println(string);
         }
         in.close();
       catch (IOException e) {
         e.printStackTrace();
       }
     }

     public static void main(String[] args) {
       if (args.length != 1) {
         System.err.println("uso: java TextReader "
           "arquivo local");
         System.exit(0);
       }
       readFile(args[0]);
     }
   }

A aproximação básica em classes assim é criar um objeto de Arquivo que corresponde ao arquivo atual no disco rígido. A classe cria um FileReader associado com o arquivo e depois um BufferedReader do FileReader. Logo após usa o leitor de BufferedFile para ler o arquivo uma linha por vez.

Para ver a classe TextReader funcioando, você precisa criar um documento para a classe ler e analisar gramaticalmente. Crie o documento, salve o seguinte texto em um arquivo  de nome TextSample.txt no mesmo diretório do TextReader:

   Aqui é um pequeno arquivo de texto que você
   usará para testar o java.util.scanner.

Compile a classe TextReader, e em seguida execute com a seguinte entrada:

   java TextReader TextSample.txt

A saída é idêntica à forma como o texto está organizado no arquivo original.

Você pode simplificar o código da classe TextReader usando java.util.Scanner. Esta é uma classe que analisa gramaticalmente tipos primitivos e strings:

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

   public class TextScanner {

     private static void readFile(String fileName) {
       try {
         File file = new File(fileName);
         Scanner scanner = new Scanner(file);
         while (scanner.hasNext()) {
           System.out.println(scanner.next());
         }
         scanner.close();
       catch (FileNotFoundException e) {
         e.printStackTrace();
       }
     }

     public static void main(String[] args) {
       if (args.length != 1) {
         System.err.println("uso: java TextScanner1"
           "arquivo local");
         System.exit(0);
       }
       readFile(args[0]);
     }
   }

Compile o TextScanner, e depois rode com a seguinte entrada:

   java TextScanner TextSample.txt

Você deve conseguir a seguinte saída

   Aqui
   é
   um
   pequeno
   arquivo
   de
   texto
   que
   você
   usará
   para
   testar
   o
   java.util.scanner.

TextScanner cria um objeto Scanner do arquivo. O Scanner quebra os símbolos do arquivo que usam um padrão como delimitador (neste caso, o espaço “ ”), por definição, o delimitador padrão é o espaço em branco. TextScanner chama o método hasNext () da classe Scanner. Este método devolve o valor indicando se existe outro símbolo delimitado pelo espaço em branco, e segue nessa repetição até o final do arquivo. O método next() retorna uma String que representa o próximo símbolo. Assim, até chegar ao final do arquivo, TextScanner imprime o String devolvido pelo método next().

Você pode mudar o delimitador que é usado para um token pelo método useDelimiter da classe Scanner. Você pode passar o delimitador em uma String ou em um java.util.regex.Pattern para o método. Veja o JavaDocs para Padrão para informação sobre quais padrões são apropriados. Por exemplo, você pode ler o arquivo de entrada uma linha o por vez usando o caractere que indica a nova linha (\ n). Neste exemplo usamos o delimitador que indica a quebra de linha:

   private static void readFile(String fileName) {
     try {
       Scanner scanner = new Scanner(new File(fileName));
       scanner.useDelimiter
         (System.getProperty("line.separator")); 
       while (scanner.hasNext()) {
         System.out.println(scanner.next());
       scanner.close();
     catch (FileNotFoundException e) {
       e.printStackTrace();
     }
   

Note que há outras opções para descobrir o fim de uma linha. Por exemplo, você poderia testar para linhas que terminam com um caráter de nova linha ou aquele fim com um retorno de carruagem e um caráter de nova linha. Você pode fazer isso usando a expressão regular "\ r\n |\n." O JavaDocs para java.util.regex.Pattern mostra outro possível delimitador de linha, assim uma verificação mais completa usaria a expressão "\ r\n|[\r\n\u2028\u2029\u0085]." Você também pode usar o método hasNextLine() e o método nextLine() da classe Scanner. Você deveria ver o seguinte:

   Aqui é um pequeno arquivo de texto que você
   usará para testar o java.util.scanner.

Uma mudança simples no delimitador usado pelo Scanner lhe dá muito poder e flexibilidade. Por exemplo, se você especificar o delimitador da seguinte forma:

   scanner.useDelimiter("\\z");

lê imediatamente o arquivo inteiro. Isto é semelhante ao truque sugerido por Pat Niemeyer em seu blog de java.net. Você pode ler o conteúdo de uma única vez sem criar vários objetos de intermediário. O código para a classe seguinte, WebPageScanner, lê todo o conteúdo do site java.net:

   import java.net.URL;
   import java.net.URLConnection;
   import java.io.IOException;
   import java.util.Scanner;

   public class WebPageScanner {
     public static void main(String[] args) {
       try {
         URLConnection connection =
           new URL("http://java.net").openConnection();
         String text = new Scanner(
           connection.getInputStream()).
           useDelimiter("\\Z").next();
       catch (IOException e) {
         e.printStackTrace();
       }
     }
   }

Você pode controlar mais que Strings com a classe Scanner. Você também pode usar Scanner para analisar gramaticalmente dados primitivos. Para ilustrar isto, salve os seguintes dados em um arquivo de nome Employee.data (no mesmo diretório de sua aplicação):

   Joe, 38, verdade
   Kay, 27, verdade
   Lou, 33, falso

Você poderia tratar isto como um Strting grande e poderia executar as conversões depois de analisar gramaticalmente a String. Ao invés disso, você pode analisar gramaticalmente este arquivo em dois passos. Isto é ilustrado na classe seguinte, DataScanner:

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

   public class DataScanner {

     private static void readFile(String fileName) {
       try {
         Scanner scanner =
           new Scanner(new File(fileName));
         scanner.useDelimiter
           (System.getProperty("line.separator")); 
         while (scanner.hasNext()) {
           parseLine(scanner.next());
         }
         scanner.close();
       catch (FileNotFoundException e) {
         e.printStackTrace();
       }
     }

     private static void parseLine(String line) {
       Scanner lineScanner = new Scanner(line);
      lineScanner.useDelimiter("\\s*,\\s*");
       String name = lineScanner.next();
       int age = lineScanner.nextInt();
       boolean isCertified = lineScanner.nextBoolean();
       System.out.println("É " + isCertified +
         " que " + name + ", tem "
         + age + " anos.");
     }

     public static void main(String[] args) {
       if (args.length != 1) {
         System.err.println("uso: java TextScanner2"
           "arquivo local");
         System.exit(0);
       }
       readFile(args[0]);
     }
   }

O objeto de Scanner lê um arquivo, uma linha de cada vez. O método readFile() passa cada linha a um segundo Scanner. O segundo Scanner analisa gramaticalmente a vírgula delimitando dados e descarta os espaços em branco em qualquer lado da vírgula. Há variantes do método hasNext() e do método next() que permitem testar se o próximo símbolo é ou não um tipo especificado e tentar tratar o próximo símbolo como um exemplo daquele tipo. Por exemplo, nextBoolean() tenta tratar o próximo símbolo como um boolean e tenta combinar "verdadeiro" ou "falso" na String. Se a combinação não pode ser feita, a excessão java.util.InputMismatchException é lançado. O método parseLine() da classe DataScanner mostra como cada linha é analisada gramaticalmente em uma String, um int, e um boolean.

Compile a classe DataScanner, e depois execute da seguinte forma:

   java DataScanner Employee.data

Você deve ver a seguinte saída:

   É verdade que Joe, tem 38.
   É verdade que Kay, tem 27 anos.
   É falso que Lou, tem 33 anos.



Eduardo Oliveira Spínola (eduspinola@gmail.com - http://eduspinola.googlepages.com/home) é Bacharel em Ciência da Computação pela Universidade Salvador - UNIFACS, em 2005. Atualmente fazendo o Mestrado em Engenharia de Software pe [...]

O que você achou deste post?
Conhece a assinatura MVP?
Publicidade
Serviços

Mais posts