Fecha y hora actual: Jueves 17 Ene 2019 05:05
Índice del Foro

Foros de programación informática, diseño gráfico y Web

En esta comunidad intentaremos dar soporte de programación a todos los niveles, desde principiantes a profesionales de la informática, desarrollo de programas, programación web y mucho más.

Curso VB .NET - Tema 1.40.1 - Archivos secuenciales, Java.

Responder al Tema

Índice del Foro > Visual Basic .NET > Curso VB .NET - Tema 1.40.1 - Archivos secuenciales, Java.

Autor Mensaje
Tesis
Administrador


Registrado: 04 Mar 2007
Mensajes: 3200
Ubicación: Valencia - España

Mensaje Publicado: Lunes 25 Ene 2010 12:22

Título del mensaje: Curso VB .NET - Tema 1.40.1 - Archivos secuenciales, Java.

Responder citando

Curso de programación en .NET - Tema 1.40.1 - Archivos secuenciales, Java.


1. Archivos secuenciales, Java.
1.1 Objetivos del tema.

Visto el acceso a un archivo, vamos a ver el acceso a un archivo secuencial utilizando un formato en ASCII delimitado como formato de grabación, que es el más estándar de todos.

1.2 Introducción.
Son archivos que se generan con una estructura que puede o no ser fija y que su lectura no puede ser direccionada.

Otro aspecto, es que por la estructura de datos generada en el archivo, la misma permita que se direccionen los registros, y que dicho archivo pueda ser abierto bajo otro formato distinto, de acceso aleatorio, pero eso es una particularidad, o una excepción, y también podríamos enfocarlo al revés, es decir es un archivo random, que se usa como archivo secuencial, para gustos los colores.

Otro aspecto sobre los archivos secuenciales, es que la estructura de datos que albergan no tiene porque ser una estructura fija, pueden ser registros con una estructura distinta de unos a otros, y además la longitud puede ser variable, siempre y cuando se este utilizando el formato de ASCII delimitado, que incorpora la delimitación de campos y de final de registro.

1.3 Grabar una estructura de datos.
Bueno visto como efectuar la lectura y escritura en un archivo secuencial, conviene ampliar el tema para un archivo con una estructura algo más amplia.
Para la estructura de datos podemos utilizar un array o una colección, con el fin de almacenar los datos a utilizar en la misma.

La grabación de los datos no es nada más que la generación de un registro de datos con un formato en concreto, uno de los más extendidos es el ASCII delimitado.
En este formato se graban los datos numéricos separados por comas y los alfanuméricos encerrados entre comillas dobles.
Al final de registro hay que incluir los caracteres que indican el final del mismo, que son el retorno de carro, ASCII 13 y 10.

Por lo tanto hay que generar un método que cree éste formato y sea capaz de leerlo, e interpretarlo después.
Crearemos una clase que nos gestione las mencionadas acciones.
La mencionada clase debe disponer de métodos que generen los separadores de campo, los delimitadores, y el fin de registro.

También hay que gestionar la lectura del registro, esa tarea se puede resolver utilizando el método StringTokenizer.

El método que graba el registro puede ser:
Código:
public void GrabaDelimitado(List Campos) throws IOException
{
   int x = 0;
   String Campo;
   while (x < Campos.size()-1)
   {
      Campo = Campos.get(x).toString();
      GrabaCampoString(Campo);
      Separador();
      ++x;
   }
   Campo = Campos.get(x).toString();
   GrabaCampoString(Campo);
   GrabaFinRegistro();
}

En éste método recibimos como argumento una colección, la cual leemos hasta el penúltimo elemento, con el fin de no grabar el separador de campos, si no el fin de registro en el último.
En el ejemplo solo se ha utilizado la creación de un campo alfanumérico, solo pretende ser un ejemplo, pero uno numérico sería igual pero sin las comillas dobles.
Código:
private void GrabaCampoString(String Dato) throws IOException
{
   Salida.write(34);
   Salida.write(Dato);
   Salida.write(34);
}

Y la separación entre campos es la siguiente:
Código:
private void Separador() throws IOException
{
   Salida.write(",");
}

La generación de la colección, para el ejemplo puede ser algo tan sencillo como:
Código:
Registro.add("Codigo");
Registro.add("Nombre");
Registro.add("1 Apellido");
Registro.add("2 Apellido");
Registro.add("Domicilio");
Registro.add("Población");
Registro.add("Cod. Postal");
Registro.add("Teléfono");


El registro sería una colección generada con LinkedList.
Código:
List Registro = new LinkedList();

Y el archivo sería un objeto de la clase anterior.
Código:
ClaseArchivos Archivo = new ClaseArchivos("C:\\", "Pruebas.txt");


Quedando el conjunto como sigue:
Código:
package archivos_secuenciales;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.List;
import java.util.LinkedList;

public class Main
{
   public static void main(String[] args)
   {
      int x=0;
      List Registro = new LinkedList();
      try
      {
         ClaseArchivos Archivo = new ClaseArchivos("C:\\", "Pruebas.txt");
         Archivo.AbrirGrabacion();
         Registro.add("Codigo");
         Registro.add("Nombre");
         Registro.add("1Apellido");
         Registro.add("2Apellido");
         Registro.add("Domicilio");
         Registro.add("Población");
         Registro.add("Cod. Postal");
         Registro.add("Teléfono");
         Archivo.GrabaDelimitado(Registro );
      }
      catch (IOException ex)
      {
         Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      }
      catch (ArithmeticException ex)
      {
         Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      }
   }
}


1.4 Leerlo.
El siguiente paso sería intentar leer el registro que hemos grabado anteriormente.
Siguiendo los pasos conocidos hemos de realizar el paso inverso, es decir en lugar de montar un registro desmontarlo en campos.

Para ello el método más adecuado sería aprovechar la existencia de StringTokenizer y utilizarlo para el despiece del registro.
Por lo tanto prime paso sería cargar una cadena con un registro completo, por lo tanto hay que montar un bucle que lea desde un carácter hasta el primer retorno de carro.

Código:
// Lectura de un registro
while ((Caracter != 13) & (Caracter != -1))
{
   if (Caracter != 10)
   {
      Cadena.append((char) Caracter);
   }
   Caracter = Entrada.read();
}


Una vez extraído un registro del archivo hay que desmontarlo.
Código:
// Extracción de los datos.
StringTokenizer Trocea = new StringTokenizer(Cadena.toString(),"\",");
while( Trocea.hasMoreTokens() )
{
   String valor = Trocea.nextToken();
   Campos.add(valor);
}


Para ello hemos usado el StringTokenizer definiendo como caracteres de control las comillas, \", y la coma, las comillas como son parte de los caracteres de control de Java debe ir precedida de la barrra inversa.

En el bucle obtendremos campo a campo su contenido, mientras se cumpla Trocea.hasMoreTokens() pasando cada uno de ellos a una colección.
Código:
Campos.add(valor);


La ventaja de usar una colección es que su tamaño es dinámico.
Finalizado el despiece del registro leemos el siguiente carácter en el archivo de esa forma podemos saber si hemos llegado al final del mismo.
Código:
Caracter = Entrada.read();
EOF = (Caracter == -1);


Y podemos devolver el true al programa.
Veamos ahora el método completo con la captura de errores incluida.
Código:
public List LeerDelimitado() throws IOException
{
   StringBuffer Cadena = new StringBuffer("");
   int Caracter;
   List Campos = new LinkedList(); // Inicializar la colección
   try
   {
      Caracter = Entrada.read();
      // Lectura de un registro
      while ((Caracter != 13) & (Caracter != -1))
      {
         if (Caracter != 10)
         {
            Cadena.append((char) Caracter);
         }
         Caracter = Entrada.read();
      }

      // Extracción de los datos.
      StringTokenizer Trocea = new StringTokenizer(Cadena.toString(),"\",");
      while( Trocea.hasMoreTokens() )
      {
         String valor = Trocea.nextToken();
         Campos.add(valor);
      }
      Caracter = Entrada.read();
      EOF = (Caracter == -1);
   }
   catch (IOException ex)
   {
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      System.out.println("Error");
   }
   return Campos;
}


Siendo su uso en el Main del programa como sigue:
Código:
package archivos_secuenciales;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.List;
import java.util.LinkedList;

public class Main {
   public static void main(String[] args)
   {
      int x=0;
      List Registro = new LinkedList();
      try
      {
         ClaseArchivos Archivo = new ClaseArchivos("C:\\", "Pruebas.txt");
         Archivo.AbrirLectura();
         Registro.removeAll(Registro);
         Registro = Archivo.LeerDelimitado();
         while (! Archivo.EOF)
         {
            x=0;
            System.out.println("[cabecera]");
            while (x < Registro.size())
            {
               System.out.print("[" + Registro.get(x).toString() + "]");
               x++;
            }
            System.out.println();
            Registro = Archivo.LeerDelimitado();
         }
         System.out.println("Finalizada la lectura");
      }
      catch (IOException ex)
      {
         Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      }
      catch (ArithmeticException ex)
      {
         Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      }
   }
}


Como se puede observar, en el principal lo que hacemos es un bucle en el que condicionamos la lectura de registros a que Registro disponga de información para su visualización,
Código:
while (x < Registro.size())
{
   System.out.print("[" + Registro.get(x).toString() + "]");
   x++;
}


Y en el bucle exterior
Código:
while (! Archivo.EOF)
{
   x=0;
   System.out.println("[cabecera]");
   while (x < Registro.size())

Del valor de EOF de la clase para mantenernos en el bucle mientras hayan datos en el archivo.

1.5 La clase completa.
Visto todo lo anterior, queda ver la clase completa.
Código:
package archivos_secuenciales;
import java.util.LinkedList;
import java.util.StringTokenizer;
import java.io.File;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ClaseArchivos
{
   public boolean EOF = false;
   String Ruta;
   File Archivo;
   FileWriter Salida;
   FileReader Entrada;
   
  public ClaseArchivos(String Ruta, String Nombre) throws IOException
   {
      Archivo = new File(Ruta + Nombre);
   }
   public void AbrirGrabacion() throws IOException
   {
      Salida = null;
      Salida = new FileWriter(Archivo);
   }
   public void AbrirLectura() throws IOException
   {
      Entrada = new FileReader(Archivo);
   }
   private void GrabaFinRegistro() throws IOException
   {
      Salida.write(13);
      Salida.write(10);
   }
   private void GrabaCampoString(String Dato) throws IOException
   {
      Salida.write(34);
      Salida.write(Dato);
      Salida.write(34);
   }
   private void GrabaCampoNumerico(String Dato) throws IOException
   {
      Salida.write(Dato);
   }
   private void Separador() throws IOException
   {
      Salida.write(",");
   }
   public void CierreGrabacion() throws IOException
   {
      Salida.close();
   }
   public void CierreLectura() throws IOException
   {
      Entrada.close();
   }
   public List LeerDelimitado() throws IOException
   {
      StringBuffer Cadena = new StringBuffer("");
      int Caracter;
      List Campos = new LinkedList(); // Inicializar la colección
      try
      {
         Caracter = Entrada.read();
         // Lectura de un registro
         while ((Caracter != 13) & (Caracter != -1))
         {
            if (Caracter != 10)
            {
               Cadena.append((char) Caracter);
            }
            Caracter = Entrada.read();
         }
         // Extracción de los datos.
         StringTokenizer Trocea = new StringTokenizer(Cadena.toString(),"\",");
         while( Trocea.hasMoreTokens() )
         {
            String valor = Trocea.nextToken();
            Campos.add(valor);
         }
         Caracter = Entrada.read();
         EOF = (Caracter == -1);
      }
      catch (IOException ex)
      {
         Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
         System.out.println("Error");
      }
      return Campos;
   }
   public void GrabaDelimitado(List Campos) throws IOException
   {
      int x=0;
      String Campo;
      while (x < Campos.size()-1)
      {
         Campo = Campos.get(x).toString();
         GrabaCampoString(Campo);
         Separador();
         ++x;
      }
      Campo = Campos.get(x).toString();
      GrabaCampoString(Campo);
      GrabaFinRegistro();
   }
}


Que por supuesto, es muy mejorable, y sobre todo ampliable, pero es un buen punto de partida.
Para el código visto el resultado de su ejecución es el siguiente.
Finalizada la grabación
Código:
[cabecera]
[Codigo][Nombre][1Apellido][2Apellido][Domicilio][Población][Cod.Postal][Teléfono]
[cabecera]
[123][Juan][Gonzalez][Martí][C/ A 23 ][Valencia ][46000][123456789]



Autor del curso: casiopea


Normas del foro
Aprende a postear correctamente usando las etiquetas
Volver arriba
Ver perfil del usuario Enviar mensaje privado
Responder al Tema
Mostrar mensajes anteriores:   
Ir a:  
Todas las horas están en GMT + 2 Horas

Temas relacionados

Tema Autor Foros Respuestas Publicado
El foro no contiene ningún mensaje nuevo

necesito ayuda con el algoritmo de dijkstra en ...

mery Python 0 Jueves 13 Dic 2018 18:07 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Ayuda con TestNG Parametrico en java netbeans

baltigo Java 0 Sábado 30 Jun 2018 01:37 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Publicar Aplicación web JAVA en tomcat

Irvin Java Web 1 Viernes 13 Oct 2017 17:54 Ver último mensaje
El foro no contiene ningún mensaje nuevo

Imagen referencial De creación de jtable en apl...

Jensel S.G Java 6 Miércoles 13 Sep 2017 20:06 Ver último mensaje
El tema está bloqueado: no pueden editarse ni agregar mensajes.

EMPLEO ANALISTA PROGRAMADOR/A BACK-END JAVA EE

GRUPOARESTORA Bolsa de trabajo 0 Viernes 23 Jun 2017 14:33 Ver último mensaje
Panel de Control
No puede crear mensajes, No puede responder temas, No puede editar sus mensajes, No puede borrar sus mensajes, No puede votar en encuestas,