En la computadora, los archivos son un bitstream o "flujo de bits". Esto es para que se puedan construir fácilmente programas que puedan escribir a cualquier tipo de flujo, ya sean archivos, la pantalla, la impresora o una red. La clase que nos srive para imprimir bits a un bitstream es PrintWriter. En la imagen de la izquierda podemos ver que el constructor del PrintWriter recibe un FileWriter, esto se debe a que el PrintWriter sabe escribir a un flujo, pero no sabe a cuál, la clase FileWriter le permite escribir a un flujo de archivos.
El constructor de FileWriter es muy importante, puede recibir uno o dos parámetros, el primer parámetro es el nombre del archivo o un objeto de la clase File que represente el archivo que queremos abrir, el segundo (que es opcional) es un boolean que indica si se debe sobreescribir el archivo o escribir al final.
Hay dos maneras de escribir a un archivo una vez que ya tenemos el PrintWriter, pero primeor tenemos que entender una cosa de esta clase. El PrintWriter es un buffer, como una caja en la que se guarda lo que se va a escribir al archivo y una vez que ya está todo listo se manda al archivo.
Para mandar un String a un archivo de texto podemos utilizar dos métodos, el primero es println() que recibe una línea de texto y la imprime en el archivo con un cambio de línea ("\n") al final, el segundo método que se utiliza frecuentemente es el método print que funciona básicamente de la misma manera, pero no pone un salto de línea al final y no imprime los
datos al archivo sino únicamente los deja en el buffer, por lo que tenemos que utilizar el método flush() para que lo imprima al archivo.
Es muy importante recordar que debemos cerrar el archivo al terminar de utilizarlo, ya que en caso contrario no estamos seguros de que todos los cambios se guarden en el archivo. Para poder cerrar el archivo utilizamos el método close() del PrintWriter.
Es muy importante recordar que debemos cerrar el archivo al terminar de utilizarlo, ya que en caso contrario no estamos seguros de que todos los cambios se guarden en el archivo. Para poder cerrar el archivo utilizamos el método close() del PrintWriter.
¿Cómo leer de archivos de texto?
El bitstream que creamos al guardar un archivo podemos leerlo mediante la clase BufferedReader. Pero al igual que la clase PrintWriter esta clase no sabe qué tipo de archivo está leyendo por lo que hay que especificarle queobtenga el bitstream desde un archivo utilizando la clase FileReader.
Para construir un FileReader lo único que tenemos que hacer es utilizar el constructor que recibe el nombre de archivo o un objeto de la clase File representando el archivo que queremos leer. Una vez que ya tenemos el FileReader debemos utilizarlo para construir un BufferedReader, de la manera que se ve a la izquierda.
Una vez que tengamos el BufferedReader podemos utilizar varios métodos que nos permiten escribir a archivos de texto. El primero que vamos a ver es el método read(), que nos devuelve un int con el código Unicode del carácter leído, para poder convertir este código en un carácter debemos utilizar un cast a char. Para hacer un cast de un tipo de dato a otro tenemos que poner la variable que queremos que reciba el valor, un símbolo de igual, el tipo de dato al que queremos convertir y el valor que queremos convertir, como se ve en la imagen de la izquierda.
El otro método del BufferedReader que nos va a ser muy útil es el método readLine(), este método nos permite leer todo un archivo mucho más rápido y nos es muy útil cuando queremos obtener datos de un archivo de inicio ya que podemos leer una línea cada vez y utilizarla de la manera que nos convenga.
Al igual que cuando utilizamos el PrintWriter debemos cerrar el archivo al terminarlo de utilizar utilizando el método close() del BufferedReader ya que aunque en este caso no se pierden datos, otros programas no van a poder utilizar el archivo hasta que lo cerremos.
Por último vamos a darle un rápido vistazo a la clase File que nos es muy útil siempre que trabajamos con archivos.
9 El constructor de File recibe un String con la ruta del archivo, una vez que creamos el objeto tipo File podemos utilizar los siguientes métodos:
f.canRead(): Devuelve un boolean verdadero en caso de que se pueda leer el archivo, falso en caso de que no se pueda leer.
f.canWrite(): Devuelve un boolean verdadero en caso de que se pueda escribir el archivo, falso en caso de que no se pueda escribir.
f.delete(): Intenta borrar el archivo, devuelve true si pudo hacerlo, false en caso de que no lo haya borrado.
f.deleteOnExit(): Borra el archivo al terminar el programa, muy útil cuando necesitamos un lugar para guardar muchos datos y no queremos saturar la memoria porque nos permite crear un archivo temporal en el que se guarden los datos.
z Para poder leer archivos de texto en Java debemos crear un objeto de tipo BufferedReader. BufferedReader es una clase que contiene métodos predefinidos para poder leer de una secuencia de bits.
z Para poder guardar archivos de texto en Java debemos crear un objeto de tipo PrintWriter. PrintWriter es una clase que contiene métodos predefinidos para meter datos a una secuencia de bits.
z Puedes hacer click en los nombres para ver el API que contiene muchos métodos útiles.
¾ BufferedReader
z El constructor que vamos a utilizar para crear un BufferedReader es: BufferedReader fileIn = new BufferedReader(new
FileReader(fileName);
z Ya que tenemos el objeto tipo BufferedReader podemos utilizar varios métodos para leer, él más común es: fileIn.readLine();
z Este método lee una línea y la devuelve o devuelve null si llegamos al final del archivo y no hay nada que leer.
z Es importante recordar cuando trabajamos con archivos que cada que leemos o escribimos a un archivo debemos hacerlo dentro de un try.
z Un try es un manejador de excepciones, cuando sucede un error en la ejecución de nuestro programa ejecuta ciertas instrucciones dependiendo del tipo de error que sucedió.
z Otro método muy importante es el método: fileIn.read();
z Este método nos permite leer un solo carácter del flujo de datos. El método regresa un número (int) del 1 al 65535 si puede leer del archivo o regresa -1 si no.
try {
BufferedReader fileIn = new BufferedReader( new FileReader(fileName));
int i = fileIn.read(); //Iniciamos una variable a la que //vamos a leer
char c = (char) i; //Como lo que leimos es un int debemos // hacer un cast a char
} catch (IOException ioe) {
} catch (FileNotFoundException fnfe) { }
¾ PrintWriter
z El constructor que vamos a utilizar para crear un PrintWriter es: PrintWriter fileOut = new PrintWriter(new FileWriter(fileName);
z Ya que tenemos el objeto PrintWriter podemos utilizar varios métodos para escribir, los más comunes son:
fileOut.print(String); fileOut.println(String);
z Estos dos métodos reciben un String y lo imprimen en el archivo, el segundo método le pone un carácter de fin de línea al final.
z Al igual que al leer debemos recordar utilizar un try. Cuando utilizamos el PrintWriter todo entra a un buffer y una vez que terminemos de escribir los datos debemos recordar utilizar el método flush() del PrintWriter para escribir todo al archivo.
z Al terminar de usar el archivo también debemos recordar que debemos cerrarlo mediante el método close() del PrintWriter.
String fileName = "Texto.txt"; PrintWriter fileOut = null;
try {
fileOut = new PrintWriter(new FileWriter(fileName)); String s = "Una linea de texto";
fileOut.println(s); fileOut.flush();
} catch (IOException ioe) {
System.out("Error, disco protegido contra lectura"); } catch (FileNotFoundException fnfe) {
System.out("Error, no se encuentra el archivo"); } finally {
if (fileIn != null) { try {
fileIn.close();
} catch (IOException ioe) { }
} }
Ejemplos:
Caso 01
package prjarchivos; import java.io.FileReader; import java.io.IOException; import javax.swing.JFrame;public class ArchivoApp2{
public static void main(String[] args) { FileReader entrada=null;
StringBuffer str=new StringBuffer(); try { entrada=new FileReader("VERARCHI01.txt"); int c; while((c=entrada.read())!=-1){ str.append((char)c); } System.out.println(str); System.out.println("---"); }
catch (IOException ex) {
System.out.println("El archivo no existe"); }
finally{
//cerrar los flujos de datos if(entrada!=null){ try{ entrada.close(); } catch(IOException ex){} }
System.out.println("el bloque finally siempre se ejecuta"); } } } Caso 02 package prjrarchivos2; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import javax.swing.JOptionPane; import pckPrincipal.FrmLlamar;
public class Class1 extends FrmLlamar{ public Class1() {
String nombre=" VERARCHI02.txt"; BufferedReader entrada;
try {
entrada = new BufferedReader(new FileReader(nombre)); String texto=""; while(true){ texto = entrada.readLine(); //JOptionPane.showMessageDialog(null,texto); if(texto==null) break; System.out.println(texto); this.txt.append(texto+"\n"); } entrada.close(); this.setVisible(true); }catch(FileNotFoundException f){ } catch (IOException e) { // TODO } } } Caso 03 package pckClase; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JOptionPane; import pckAplica.FrmArchivo3;
public class ClassAr3 {
public String datos[]=new String[50]; public int i,pos,tam;
public ClassAr3() { }
public void llamar(){ String subStr="";
String nombre="ArchivoApp2.txt"; BufferedReader entrada;
try {
String texto=""; while(true){ texto = entrada.readLine(); /* tam=texto.length(); for(int g=0;g<tam;++g){ String j=String.valueOf(texto.charAt(g)); //JOptionPane.showMessageDialog(null,j); if(j.equals(",")){ datos[i]=subStr; ++i; } else subStr=subStr+j; } */ if(texto==null) break; System.out.println(texto); } entrada.close(); }catch(FileNotFoundException f){ } catch (IOException e) { // TODO } } }
Caso Práctico: Usando la Técnica P.O.O:
Guarda registro, código, Nombre, Apellido, Carrera y pago dentro de un Archivo. Para ello cree la siguiente estructura de trabajo.
Desarrollo:
9 En el paquete Paneles se usaran: Contenido(tendrá los controles para el ingreso de datos) y pie(presentara la fecha y hora del sistema, utilizaremos el GregorianCalendar). 9 En la capa lógica 2 subclases: ClassEncapsulada(se crearan los get y set por cada
atributo que se tenga) y ClassMetodos(se creara los métodos para generar el código y hallar el pago de acuerdo a la especialidad)
9 Los Frame son los objetos visualizadores de los paneles
Empecemos a codificar
package pckLogico;
public class ClassEncapsulada {
String nom,ape,cod; int p,reg;
public String getNom() { return nom;
}
public void setNom(String nom) { this.nom = nom;
}
public String getApe() { return ape;
public void setApe(String ape) { this.ape = ape;
}
public int getP() { return p; }
public void setP(int p) { this.p = p;
}
public int getReg() { return reg; }
public void setReg(int reg) { this.reg = reg;
}
public String getCod() { return cod;
}
public void setCod(String cod) { this.cod = cod;
}
}// fin de la clase encapsulada package pckLogico;
public class ClassMetodos {
int x=11,dv,pag;
GregorianCalendar formato=new GregorianCalendar(); int devNV(char letra){
switch(letra){
case 'a':case 'A':dv=1;break; case 'e':case 'E':dv=2;break; case 'i':case 'I':dv=3;break; case 'o':case 'O':dv=4;break; case 'u':case 'U':dv=5;break; default : dv=x;
++x; }
return(dv); }
public String genera(String cadN,String cadA){ int año=formato.get(formato.YEAR);
int mes=formato.get(formato.MONTH)+1; //Datos del Nombre
int largoN=cadN.length();
char n2=cadN.charAt(largoN-1); //datos del Apellido
char a1=cadA.charAt(0); int largoA=cadA.length(); char a2=cadA.charAt(largoA-1); String cad=(""+año+devNV(n1)+devNV(n2)+devNV(a1)+devNV(a2)+mes); return(cad); }
public int pago(int index){ switch(index){ case 1: pag=850;break; case 2: pag=750;break; case 3: pag=600;break; case 4: pag=700;break; case 5: pag=750;break; case 6: pag=680;break; } return(pag); }
}// fin de la clase Metodos
Uso de los paneles: diseñe todo este formato
package pckPaneles;
public class pnlContenido extends JPanel {
ClassMetodos llamar=new ClassMetodos(); ClassEncapsulada atri=new ClassEncapsulada(); ClassArchivo datos=new ClassArchivo();
int dv,c=1,x=11;
String titulos[]={"Registro","Codigo","Nombres","Apellidos","Categoria","Pago"}; String contenido[][]={};
private JTextField TXTNOM = new JTextField(); private JTextField TXTAPE = new JTextField(); private JComboBox cboespe = new JComboBox(); private JLabel lblp = new JLabel();
private JSeparator jSeparator1 = new JSeparator(); private JSeparator jSeparator2 = new JSeparator(); private JButton btnañadir = new JButton();
private JButton btnsalir = new JButton();
private JScrollPane jScrollPane1 = new JScrollPane(); private JTable jTable1 = new JTable();
private DefaultTableModel modtbdatos = new DefaultTableModel(contenido,titulos); private JButton btnLsitaAr = new JButton();
*******************
private void jbInit() throws Exception {
modtbdatos.setColumnCount(6); *************************** jTable1.setModel(modtbdatos); cboespe.addItem("Seleccionar cat"); cboespe.addItem("Sistemas"); cboespe.addItem("Redes"); cboespe.addItem("Diseño Grafico"); cboespe.addItem("Contabilidad"); cboespe.addItem("Administracion"); cboespe.addItem("Otros"); }
private void btnañadir_actionPerformed(ActionEvent e) {
atri.setReg(c); x=11; atri.setNom(TXTNOM.getText()); atri.setApe(TXTAPE.getText()); atri.setCod(llamar.genera(atri.getNom(),atri.getApe())); Object valores[]={atri.getReg(),atri.getCod(),atri.getNom(),atri.getApe(),cboespe.getSelectedItem(),atri. getP()}; modtbdatos.addRow(valores); datos.Grabar(atri.getReg(),atri.getCod(),atri.getNom(),atri.getApe(),atri.getCod(),atri.getP()); ++c; }
private void cboespe_actionPerformed(ActionEvent e) {
atri.setCod(cboespe.getSelectedItem().toString()); lblp.setText(""+atri.getP());
atri.setP(llamar.pago(cboespe.getSelectedIndex()));
}
private void btnListaAr_actionPerformed(ActionEvent e) { Frmlectura x=new Frmlectura();
x.setVisible(true); }
// Panel Pie
package pckPaneles;
public class pnlPie extends JPanel {
GregorianCalendar formato=new GregorianCalendar(); ************************ private void jbInit() throws Exception { ******************************** int dia=formato.get(formato.DAY_OF_MONTH); int mes=formato.get(formato.MONTH)+1; int año=formato.get(formato.YEAR); lblf.setText(""+dia+"/"+mes+"/"+año); lblf.setFont(new Font("Dialog", 1, 11)); int hora=formato.get(formato.HOUR_OF_DAY); int min=formato.get(formato.MINUTE); int seg=formato.get(formato.SECOND); lblh.setFont(new Font("Dialog", 1, 11)); lblh.setText(""+hora+":"+min+":"+seg); }
}//fin del panel pie
// estableciendo los paneles al Frame package pckPresentacion;
public class FrmPresenta extends JFrame {
int dv=0;
ClassEncapsulada atri=new ClassEncapsulada();
GregorianCalendar formato=new GregorianCalendar(); private pnlPie pnlPie1 = new pnlPie();
private pnlContenido pnlEncabezado1 = new pnlContenido();
public FrmPresenta() { try { jbInit(); } catch (Exception e) { e.printStackTrace(); } }
private void jbInit() throws Exception {
this.getContentPane().setLayout( null ); this.setSize(new Dimension(400, 408)); this.setResizable(false);
pnlPie1.setBounds(new Rectangle(0, 345, 395, 40)); pnlEncabezado1.setBounds(new Rectangle(0, 0, 395, 345)); this.getContentPane().add(pnlEncabezado1, null); this.getContentPane().add(pnlPie1, null); } }
Contenidos
- Definición de la Clase Vector. - Definición de la Clase ArrayList. - Diferencias entre ellas
- Métodos de la clase Vector y ArrayList
- Aplicando atributos encapsulados usando estas clases - Definición de la la Clase Hashtable.
- Métodos get y put
____________________________________________________________________________
¾ Vector
Es una clase que permite crear matrices dinámicas, es decir matrices que varían en cantidad de elementos durante la ejecución del programa, lo cual no se puede hacer en java con la clase Array que es la clase que generalmente se utiliza para crear matrices.
En un Vector, puedo agregar cualquier cosa, incluso puedo agregar diferentes tipos de objetos a un mismo vector, esto se debe a que Vector almacena objetos de tipo Object que es la clase base de Java. Esto no puedo hacerlo con un Array ya que todos sus elementos deben ser del mismo tipo.
Por este motivo, cuando accedo a un elemento de un Vector, debo moldearlo a su tipo específico de datos, de lo contrario obtendré un objeto de tipo Object.
La clase Enumeration se utiliza con un vector o mejor dicho, se crea a partir de la cantidad de
elementos de un vector, ya que lo único que hace Enumeration es enumerar los elementos de un vector. Enumeration lo único que hace es recorrer los elementos de un vector hacia adelante mediante el método nextElement (), asegurando que nunca se pasará del índice del vector, esto lo hace mediante el método hasMoreElements().
Solo para eso sirve Enumeration, pero asegura que no habrá error por salirse del índice del vector. Este es un ejemplo de cómo utilizar ambas clases juntas: