sábado, 14 de julio de 2012

4.2.2 StringTokenizer y StreamTokenizer


StringTokenizer y StreamTokenizer

Pertenece a java.util.StringTokenizer
Tokenizing es el proceso de romper un String en pequeñas piezas llamadastokens.
Estos tokens están delimitados por uno o varios caracteres.
Los delimitadores más comunes son: el espacio, la coma y el guión bajo. Pero cualquier caracter puede ser delimitador.
Comúnmente lo utilizamos cuando tenemos un archivo y sacamos líneas de datos de el.
Sus métodos son:
Al crear un objeto de la clase StringTokenizer, si no se define el delimitador, este es como un espacio, o a menos que con otro constructor se defina el delimitador, esta clase nos va a ayudar a obtener datos dentro de una línea de datos o un String, como se ve a continuación.
Considera la siguiente aplicación con un Área de Texto donde se muestran los resultados.
 String  s = "This string has five tokens";
StringTokenizer  st = new  StringTokenizer(s);

int  i = 1;
while (st.hasMoreTokens())  {
 textAreaSalida.appened("Token #" + i + ":  " +
st.nextToken());
 ++i;
}
El código anterior considera el espacio como delimitador default. Y desplegará lo siguiente:
Token #1:  This
Token #2:  string
Token #3:  has
Token #4:  five
Token #5:  tokens
A continuación se da un ejemplo de grabar un archivo con varios datos, pero usando un delimitador al grabar, esta aplicación podría ser como la siguiente:
import java.io.*;
public class AplicacionFiles3 {
public static void main(String[] args) throws IOException {
 BufferedReader ent = new BufferedReader(new InputStreamReader(System.in));
 PrintWriter sal = new  PrintWriter(new FileWriter("datos.txt"));
 PrintWriter salErr = new  PrintWriter(System.err, true);
 salErr.println("Da el numero (negativo para salir)");
 int numero = Integer.parseInt(ent.readLine());
 String nombre;
 double saldo;
 while (numero > 0) {
  salErr.println("Da el nombre");
  nombre = ent.readLine();
  salErr.println("Da el saldo");
  saldo = Double.parseDouble(ent.readLine());
  // se graba la linea pero usando el delimitador guion bajo
  sal.println("" + numero + "_" + nombre + "_" + saldo );
  salErr.println("Da el número (negativo para salir)");
  numero = Integer.parseInt(ent.readLine());
 }
 salErr.println("Fin");
 sal.close();
}
}
La ejecución de la aplicación podría ser:
Donde el archivo que se grabó sería:
Ahora la manera de leer estos datos es utilizando el StringTokenizer después de leer el objeto de la clase String, tomando el “_” como delimitador. La siguiente aplicación toma línea por línea del archivo y extrae los tokens que son número, nombre y saldo:
import java.io.*;
import java.util.*;
public class AplicacionFiles4 {
public static void main(String[] args) throws IOException {
 BufferedReader ent = new BufferedReader(new FileReader("datos.txt"));
 PrintWriter sal = new  PrintWriter(System.out,true);
 PrintWriter salErr = new  PrintWriter(System.err, true);
 int numero;
 String nombre;
 double saldo;
 StringTokenizer stt;

 String linea = ent.readLine();
 while (linea != null) {
  // se tokeniza la linea leida del archivo
  stt = new StringTokenizer(linea, "_");
  // se extrae cada uno de los tokens de la línea
  numero = Integer.parseInt(stt.nextToken());
  nombre = stt.nextToken();
  saldo = Double.parseDouble(stt.nextToken());
  sal.println("" + numero + " " + nombre + " " + saldo);
  linea = ent.readLine();
 }
 salErr.println("Fin");
 ent.close();
}
}
La ejecución de esta aplicación seria:
En la aplicación anterior debemos proteger la aplicación por si hay algún error al momento de tomar el archivo y que no contenga los datos como se espera, es decir supongamos que en lugar de tener tres valores por línea solo tuviera dos, veamos que pasaría:
Al ejecutar la aplicación nos daría :
Esto es porque al crear el valor double que no se encuentra en la primera línea del archivo, el nextToken no encuentra nada en esa línea, por lo tanto el error de ejecución sería NoSuchElementException.
Utilizando el try/catch podemos corregir este error, la aplicación nos quedaría como:
import java.io.*;
import java.util.*;
public class AplicacionFiles4 {
public static void main(String[] args) throws IOException {
 BufferedReader ent = new BufferedReader(new FileReader("datos.txt"));
 PrintWriter sal = new  PrintWriter(System.out,true);
 PrintWriter salErr = new  PrintWriter(System.err, true);
 int numero;
 String nombre;
 double saldo;
 StringTokenizer stt;

 String linea = ent.readLine();
 while (linea != null) {
  try {
   // se tokeniza la linea leida del archivo
   stt = new StringTokenizer(linea, "_");
   // se extrae cada uno de los tokens de la línea
   numero = Integer.parseInt(stt.nextToken());
   nombre = stt.nextToken();
   saldo = Double.parseDouble(stt.nextToken());
   sal.println("" + numero + " " + nombre + " " + saldo);
  }
  catch (NoSuchElementException nsee) {
   salErr.println("No hay datos completos " + linea + nsee.toString());
  }
  linea = ent.readLine();
 }
 salErr.println("Fin");
 ent.close();
}
}
Suponiendo que tenemos el archivo con la primera línea correcta y la segunda no:
La aplicación ejecutada seria la siguiente:
Observamos que la primera línea esta correcta, pero en la segunda hay error y al mandar la línea a desplegar podemos observar que solo lleva hasta el nombre.
StreamTokenizer
El StreamTokenizer trabaja igual que el StringTokenizer, pero la diferencia radica en el tamaño del objeto a ser tokenizado, es decir el StringTokenizer utiliza un String el cual tiene un límite definido, mientras que el StreamTokenizer toma como parámetros un objeto de la clase InputStream o un objeto de la clase Reader.
Cuenta con una serie de métodos para tokenizer:

No hay comentarios:

Publicar un comentario