jueves, 13 de septiembre de 2012

Escritura y lectura de archivos

La escritura y lectura de archivos en Java, se pueden realizar con una manejo muy similar al de salidas y entradas estándar.

Java provee las siguientes clases

  • Para representar un archivo
    • File
  • Para lectura y escritura en archivos de texto
    • FileReader
    • FileWritter
  • Para lecturay escritura en bytes
    • FileInputStream
    • FileOutputStream

Se puede construir un objeto de cualquiera de estas clases a partir de un String que contenga el nombre o la dirección en disco del archivo o con un objeto instancia de la clase File que representa dicho archivo.

CLASE FILE

La clase File permite representar un archivo o directorio. Esta clase provee información acerca del archivo o directorio en disco. La clase File no abre archivos ni proporciona servicios para procesar archivos. Al crear un objeto de la clase File, es necesario indicar el nombre del archivo o su ruta. Si se proporciona el nombre, Java intentara encontrar el archivo en el directorio donde se ejecuta la aplicación de Java. La clase File pertenece al paquete java.io.

Retorno Metodo Descripcion
Void File(String pathname) Constructor que crea un File abriendo el archivo especificado en el parámetro.
boolean canExecute() Retorna verdadero si la aplicación puede ejecutar el archivo denotado en la ruta del File
boolean canRead () Retorna verdadero si la aplicación puede leer el archivo denotado en la ruta del File
boolean canWrite () Retorna verdadero si la aplicación puede escribir en el archivo denotado en la ruta del File
int compareTo(File pathname) Compara la ruta del File con la del parámetro alfabéticamente. Si son iguales retorna 0
boolean createNewFile() Crea un archivo vacio si el archivo con el nombre del File no existe
boolean delete() Elimina el archivo denotado en la ruta del File
boolean exists() Retorna verdadero si el archivo denotado en la ruta del File existe
File getAbsoluteFile() Retorna la forma absoluta de la ruta del archivo
File getCanonicalFile () Retorna la forma canónica de la ruta del archivo
String getName() Retorna el nombre del archivo o directorio representado en el File
boolean isDirectory() Retorna verdadero si la ruta que representa el File es un directorio
boolean isFile() Retorna verdadero si la ruta que representa el File es un archivo
boolean isHidden() Retorna verdadero si el archivo denotado en la ruta del File está oculto
long lastModified() Retorna el tiempo en el archivo denotado en la ruta del File fue modificado
long length() Retorna el tamaño en bytes del archivo denotado en la ruta del File
boolean mkdir() Crea un directorio llamado con el nombre y ruta denotado en el File
boolean setReadOnly() Establece como archivo de solo lectura el archivo denotado en la ruta del File
boolean setWritable(boolean writable) Establece como archivo escribible el archivo denotado en la ruta del File
Ejemplo de uso de los métodos createNewFile, getAbsoluteFile, getName, isDirectory, isFile, lastModified y length
import java.io.File;
import java.io.IOException;
import java.util.Date;

public class EjemplosArchivos {

 public static void main(String[] args) {
  File archivo = new File("archivo.txt");
  System.out.println("El nombre del archivo es:"+archivo.getName());
  System.out.println("La ruta absoluta del archivo es: "+archivo.getAbsoluteFile().toString());
  try {
   if(archivo.createNewFile()){
    System.out.println("El archivo fue creado");;
   }else{
    System.out.println("El archivo NO fue creado");;
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
  System.out.println("Es directorio? "+archivo.isDirectory());
  System.out.println("Es archivo? "+archivo.isFile());
  System.out.println("Fecha de modificacion: "+archivo.lastModified());
  Date fecha = new Date(archivo.lastModified());
  System.out.println("Fecha de modificacion: "+fecha.toString());
  System.out.println("Tamano "+archivo.length());
 }
}
Salida Estandar
El nombre del archivo es:archivo.txt
La ruta absoluta del archivo es: D:\eclipse europa\workspace\Libro POO\archivo.txt
El archivo fue creado
Es directorio? false
Es archivo? true
Fecha de modificacion: 1278975592406
Fecha de modificacion: Mon Jul 12 22:59:52 GMT 2010
Tamano 0  
ARCHIVOS SECUENCIALES

Los archivos secuenciales o también llamados archivos de texto plano, permiten la lectura de su información en cualquier editor de texto.

Escritura en archivo secuencial

La escritura en un archivo secuencial, puede hacerse mediante el uso de las clases File, FileWriter y BufferedWriter.

La clase BufferedWriter requiere un objeto instancia de la clase FileWriter para poder abrir el archivo. A su vez, opcionalmente la clase FileWriter puede requerir un objeto instancia de la clase File. Si no se desea usar un objeto de la clase File, al crear el objeto de la clase FileWriter, se debe incluir la ruta del archivo.

Es importante tener en cuenta que si se intenta abrir un archivo con la clase FileWriter y este no existe, entonces Java lo crea.

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;

public class EjemplosArchivos {

 /**
  * @author Hector Florez
  */
 public static void main(String[] args) {
  try {
   File archivo = new File("archivo.txt");
   FileWriter fw = new FileWriter(archivo);
   BufferedWriter bw = new BufferedWriter(fw);
   for(int i=1; i<=10; i++){
    bw.write("Escritura en archivo # "+i);
    bw.newLine();
   }
   bw.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
Archivo “archivo.txt”
Escritura en archivo # 1
Escritura en archivo # 2
Escritura en archivo # 3
Escritura en archivo # 4
Escritura en archivo # 5
Escritura en archivo # 6
Escritura en archivo # 7
Escritura en archivo # 8
Escritura en archivo # 9
Escritura en archivo # 10
Lectura en archivo secuencial

Para realizar la lectura en un archivo secuencial, se puede hacer mediante el uso de las clases File, FileReader y BufferedReader.

La clase BufferedReader requiere un objeto instancia de la clase FileReader para poder abrir el archivo. A su vez opcionalmente la clase FileReader puede requerir un objeto instancia de la clase File. Si no se desea usar un objeto de la clase File, al crear el objeto de la clase FileReader, se debe incluir la ruta del archivo.

Es importante tener en cuenta que si se intenta abrir un archivo con la clase FileReader y este no existe, entonces se presenta una excepción controlada por la clase FileNotFoundException.

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

public class EjemplosArchivos {

 public static void main(String[] args) {
  try {
   File archivo = new File("archivo.txt");
   FileReader fr = new FileReader(archivo);
   BufferedReader br = new BufferedReader(fr);
   String cadena;
   while((cadena=br.readLine())!=null){
    System.out.println(cadena);
   }   
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
Salida Estandar
Texto en archivo # 1
Texto en archivo # 2
Texto en archivo # 3
Texto en archivo # 4
Texto en archivo # 5
Texto en archivo # 6
Texto en archivo # 7
Texto en archivo # 8
Texto en archivo # 9
Texto en archivo # 10
ARCHIVOS SERIALIZABLES

Los archivos serializables tienen la característica de poder almacenar objetos y no texto. Un archivo serializable lo crea un aplicación y esta misma debe estar en la capacidad de leer e interpretar dicho archivo.

Los objetos en un archivo se visualizan como un conjunto de caracteres que no son legibles, es decir, no forman ningún mensaje consistente. Sin embargo para la aplicación que crea el archivo, estos caracteres son directamente el objeto.

Para poder almacenar un objeto en un archivo serializable, la clase debe implementar la interface “Serializable” que no define ningún método. Casi todas las clases del API de Java son serializables.

Considerando la siguiente clase Persona como serializable, los objetos que sean instancia de ella, pueden ser almacenados en un archivo serializable.

import java.io.Serializable;

public class Persona implements Serializable {
 private int id;
 private String nombre;
 private String apellido;
 private String correo;
 
 public Persona(int id, String nombre, String apellido, String correo) {
  this.id = id;
  this.nombre = nombre;
  this.apellido = apellido;
  this.correo = correo;
 }

 public int getId() {
  return id;
 }
 
 public void setId(int id) {
  this.id = id;
 }
 
 public String getNombre() {
  return nombre;
 }
 
 public void setNombre(String nombre) {
  this.nombre = nombre;
 }
 
 public String getApellido() {
  return apellido;
 }
 
 public void setApellido(String apellido) {
  this.apellido = apellido;
 }
 
 public String getCorreo() {
  return correo;
 }
 
 public void setCorreo(String correo) {
  this.correo = correo;
 }

 public String toString(){
  return 
  "id:"+this.id+
  "; Nombre: "+this.nombre+
  "; Apellido: "+this.apellido+
  "; Correo: "+this.correo;
 }
}
Escritura en archivo serializable

Para realizar la lectura en un archivo serializable, se puede hacer mediante el uso de las clases File, FileOutputStream y ObjectOutputStream.

La clase ObjectOutputStream requiere un objeto instancia de la clase FileOutputStream para poder abrir el archivo. A su vez opcionalmente la clase FileOutputStream puede requerir un objeto instancia de la clase File. Si no se desea usar un objeto de la clase File, al crear el objeto de la clase FileOutputStream, se debe incluir la ruta del archivo.

Es importante tener en cuenta que si se intenta abrir un archivo con la clase ObjectOutputStream y este no existe, entonces Java lo crea.

Con base en la clase Persona que implementa serializable, se hace la siguiente implementación

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class EjemplosArchivos {

 public static void main(String[] args) {
  Persona p;
  try {   
   File archivo = new File("archivo.txt");
   FileOutputStream fos = new FileOutputStream(archivo);
   ObjectOutputStream oos = new ObjectOutputStream(fos);
   p=new Persona(1,"Hector","Florez","hf@hectorflorez.com");
   oos.writeObject(p);
   p=new Persona(2,"Arturo","Fernandez","af@hectorflorez.com");  
   oos.writeObject(p);
   p=new Persona(3,"Juan","Valdez","jv@hectorflorez.com");   
   oos.writeObject(p);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

En el caso anterior, se ha replicado la línea de código que usa el método writeObject. Una solución interesante es utilizar la clase Vector la cual también implementa Serializable. De esta forma al escribir en el archivo, se escribe un Vector el cual contiene muchos objetos.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Vector;

public class EjemplosArchivos {

 public static void main(String[] args) {
  Persona p;
  Vector v = new Vector();
  p=new Persona(1,"Hector","Florez","hf@hectorflorez.com");
  v.add(p);
  p=new Persona(2,"Arturo","Fernandez","af@hectorflorez.com");  
  v.add(p);
  p=new Persona(3,"Juan","Valdez","jv@hectorflorez.com");   
  v.add(p);
  try {   
   File archivo = new File("archivo.txt");
   FileOutputStream fos = new FileOutputStream(archivo);
   ObjectOutputStream oos = new ObjectOutputStream(fos);
   oos.writeObject(v);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
Lectura en archivo serializable

Para realizar la lectura en un archivo serializable, se puede hacer mediante el uso de las clases File, FileInputStream y ObjectInputStream.

La clase ObjectInputStream requiere un objeto instancia de la clase FileInputStream para poder abrir el archivo. A su vez opcionalmente la clase FileInputStream puede requerir un objeto instancia de la clase File. Si no se desea usar un objeto de la clase File, al crear el objeto de la clase FileInputStream, se debe incluir la ruta del archivo.

Es importante tener en cuenta que si se intenta abrir un archivo con la clase ObjectInputStream y este no existe, entonces se presenta una excepción controlada por la clase FileNotFoundException.

En la lectura, se leer del archivo objetos, lo cual hace necesario realizar el “casting” correspondiente.

Con base en la clase Persona que implementa serializable, se hace la siguiente implementación.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class EjemplosArchivos {

 public static void main(String[] args) {
  Persona p;
  try {   
   File archivo = new File("archivo.txt");
   FileInputStream fis = new FileInputStream(archivo);
   ObjectInputStream ois = new ObjectInputStream(fis);
   p=(Persona)ois.readObject();
   System.out.println(p.toString());
   p=(Persona)ois.readObject();
   System.out.println(p.toString());
   p=(Persona)ois.readObject();
   System.out.println(p.toString());   
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
 }
}
Salida Estándar
id:1; Nombre: Hector; Apellido: Florez; Correo: hf@hectorflorez.com
id:2; Nombre: Arturo; Apellido: Fernandez; Correo: af@hectorflorez.com
id:3; Nombre: Juan; Apellido: Valdez; Correo: jv@hectorflorez.com

De la misma forma que en la escritura, se ha replicado la línea de código que usa el método readObject. Con base en la solución planteada usando la clase Vector, se puede realizar la implementación realizando la lectura de un solo objeto. Esta modificación agrega robustez a la aplicación, debido a que solo lee un objeto instancia de la clase Vector, el cual puede contener diferentes objetos instancias de diferentes clases.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Iterator;
import java.util.Vector;

public class EjemplosArchivos {

 public static void main(String[] args) {
  Persona p;
  Vector v = new Vector();
  try {   
   File archivo = new File("archivo.txt");
   FileInputStream fis = new FileInputStream(archivo);
   ObjectInputStream ois = new ObjectInputStream(fis);
   v=(Vector)ois.readObject();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
  Iterator iterator = v.iterator();
  while(iterator.hasNext()){
   p=(Persona)iterator.next();
   System.out.println(p.toString());    
  }
 }
}
Salida Estándar
id:1; Nombre: Hector; Apellido: Florez; Correo: hf@hectorflorez.com
id:2; Nombre: Arturo; Apellido: Fernandez; Correo: af@hectorflorez.com
id:3; Nombre: Juan; Apellido: Valdez; Correo: jv@hectorflorez.com  

En los dos casos, la salida es exactamente igual ya que la información que se imprime en la salida estándar es proporcionada por la clase Persona la cual no ha recibido ninguna modificación.

1 comentario: