Bienvenidos sean a este post, hoy hablaremos sobre como manejar archivos desde Java tanto para la lectura como para la escritura. El paquete encargado de este es java.io, en este paquete tendremos todos los streams necesarios para estas tareas, permitiendonos manipular todo tipo de archivos, los streams pueden ser de dos tipos:

  • InPutStream, se usa para leer desde el origen
  • OutPutStream, se usa para escribir en un destino

Estas funciones soportan mucho tipo de datos y redes pero nosotros nos centraremos en los mas utilizados.

Byte streams

Se usan para crear o leer por medio de bytes de 8-bit, si bien hay muchas clases relacionadas con este tipo de stream las mas usadas son: FileInputStream y FileOutputStream, estos metodos nos permitirian leer segmentos y poder escribirlos en su destino, veamos un ejemplo:

import java.io.*;

public class CopyFile
{

        public static void main(String[] args)
                                throws IOException
        {
                FileInputStream in = null;
                FileOutputStream out = null;

                try
                {
                        in = new FileInputStream("entrada.txt");
                        out = new FileOutputStream("salida.txt");

                        int c;
                        while(( c = in.read()) != -1)
                        {
                                out.write(c);
                        }
                }
                finally
                {
                        if (in!=null)
                                in.close();
                        if (out != null)
                                out.close();
                }
        }
}

En este ejemplo vamos a crear una clase donde nos permitira copiar el contenido de un archivo en otro, observen como utilizamos el paquete java.io.* para que usen todas las clases pertenecientes a ella, despues para poder utilizarla debemos hacer una modificacion en nuestro main() para especificarle que utilice el IOException para poder tener acceso a las clases necesarias, primero crearemos dos objetos: uno derivado de la clase FileInputStream (in) y otro de la clase FileOutputStream (out), a ambos le daremos un valor de null, despues utilizaremos un metodo try pero no para capturar un error, a nuestros objetos in y out le asignaremos por medio del metodo new y a traves del constructor correspondiente le informaremos los archivos a leer y escribir respectivamente, despues creareamos una variable de tipo int llamada c, luego usaremos un ciclo por medio de while donde a c le diremos que lea al archivo informado en el objeto in y esta sea distinto de -1, esto significa que sea distinto al final del archivo, mientras hace esto esto va escribiendo en el archivo informado en out el contenido de c, una vez terminado tendremos un metodo llamado finally donde usaremos dos condicionales que si in y out son distintas de null cierra los objetos y por ende liberando los archivos.

Nota: Antes de compilarlo y ejecutarlo generen un archivo llamado entrada.txt y pueden ponerle el siguiente texto:

Este sera un año espectacular para aprender algo nuevo!

Con el archivo generado podemos compilar nuestro programa, ejecutarlo pero no nos dara ningun mensaje de notificacion sino simplemente creara un nuevo archivo llamado salida.txt con el mismo mensaje utilizado en entrada.txt pasemos al siguiente tipo de stream

Character Stream

Este es otro tipo de stream muy similar al anterior pero en lugar de usar bytes de 8-bits utilizamos unicode de 16 bits, al igual que el caso anterior tiene varios metodos para poder trabajar pero los mas utilizados son FileReader y FileWriter, a su vez estos dos para efectuar sus tareas utilizan los metodos FileInputStream y FileOutputStream respectivamente pero la mayor diferencia es que los metodos FileReader y FileWriter utilizan dos bytes simultaneamente.
Tomemos el ejemplo anterior y efectuemos las siguientes modificaciones:

FileInputStream in = null;             
FileOutputStream out = null;

Por estas dos lineas:

FileReader in = null;             
FileWriter out = null;

Reemplazamos las clases de los objetos para poder ser utilizados por los stream de caracteres, nuestra siguiente modificacion sera en estas lineas:

in = new FileInputStream("entrada.txt");
out = new FileOutputStream("salida.txt");

Por estas otras lineas:

in = new FileReader("entrada.txt");
out = new FileWriter("salida.txt");

Como pueden ver le informamos a los nuevos constructores los archivos para leer y el de salida, nuestro codigo quedara de la siguiente manera:

import java.io.*;

public class CopyFile
{

        public static void main(String[] args)
                                throws IOException
        {
                FileReader in = null;
                FileWriter out = null;

                try
                {
                        in = new FileReader("entrada.txt");
                        out = new FileWriter("salida.txt");

                        int c;
                        while(( c = in.read()) != -1)
                        {
                                out.write(c);
                        }
                }
                finally
                {
                        if (in!=null)
                                in.close();
                        if (out != null)
                                out.close();
                }
        }
}

El funcionamiento es exactamente al mismo pero ahora en lugar de usar una forma de copiar el archivo utiliza otra, al igual que el caso anterior deberan tener un archivo llamado entrada.txt, les recomiendo borrar el archivo antes generado, compilenlo y ejecutenlo, recuerden que no devuelve ningun mensaje solamente nos hace una copia del archivo de entrada (entrada.txt), si se los copio (nuevamente) vamos por el buen camino, verifiquen que tenga el mismo texto como se ve a continuacion:

tinchicus@dbn001vrt:~/programacion/java/program$ cat entrada.txt
Este sera un año espectacular para aprender algo nuevo!
tinchicus@dbn001vrt:~/programacion/java/program$ cat salida.txt
Este sera un año espectacular para aprender algo nuevo!
tinchicus@dbn001vrt:~/programacion/java/program$

Con esto hemos cubierto dos de los dos streams mas comunes que podremos utilizar para manipular archivos, pasemos a ver uno para manejar la Entrada/Salida.

Standard Streams

Todos los lenguajes poseen un standard para manejar la E/S, Java tambien posee un soporte para permitir al usuario ingresar por medio de un teclado y mostrarlo en una pantalla, en C daba la posibilidad de enviarlo a la impresora pero era otra epoca, en C o C++ se utilizaba STDIN, STDOUT y STDERR pero en Java utilizaremos los siguientes:

  • System.in, Standard Input, es la interfaz de ingresar datos al programa, en general es el teclado
  • System.out, Standard Output, es donde se mostrara la informacion generada por el usuario, en general es el monitor
  • System.err, Standard Error, es el encargado de mostrar el error producido por la data del usuario, en general es el monitor

Para entender un poco mejor este concepto veamos el siguiente ejemplo:

import java.io.*;

public class ReadConsole
{
        public static void main(String[] args)
                        throws IOException
        {
        InputStreamReader cin = null;

        try
        {
        cin = new InputStreamReader(System.in);
        System.out.println("Ingresa Caracteres, 'q' para salir");
        char c;
        do
        {
        c = (char) cin.read();
        System.out.print(c);
        } while(c != 'q');
        }
        finally
        {
        if (cin != null)
                cin.close();
        }
        }
}

El inicio es similar a los casos anteriores pero esta vez utilizaremos la clase InputStreamReader con la cual crearemos un objeto llamado cin, esta clase se encarga de leer todos los datos que ingresemos para este caso por teclado, dentro del bloque try a cin le asignaremos por medio del new y el constructor la forma de ingreso, en este caso System.in, luego mostraremos un mensaje para ingresar los caracteres e indicando que q sera la salida, despues crearemos una variable de tipo char llamada c, despues tendremos un bucle de do…while, donde primero asignara a c todo el contenido dentro de cin por medio del metodo read(), y despues por medio de la siguiente linea mostraremos el contenido de c, y el while se encargara de chequear si c es distinto de q para hacer otro bucle. Terminando con el bucle en el bloque de finally primero verificara si cin es distinto de null y en caso de ser verdadero procedera a cerrarlo y finalizando el programa.

Si lo compilamos y ejecutamos podremos hacer lo mismo que se hace en el siguiente video

Como pueden ver a medida que ingresamos los caracteres y presionamos Enter este nos lo muestra abajo siempre y cuando no ingresemos el caracter q donde saldra del programa.

En resumen, hoy hemos visto como manipular archivos, por medio del byte stream, tambien por medio del character stream, hemos visto como se puede leer informacion de un archivo, como escribirla en un archivo, como crear un programa de copia de archivo, tambien el standard stream, el cual es encargado de poder interactuar con los sistemas de entrada y salida como un teclado (entrada) y un monitor (salida), hemos visto un ejemplo y como funciona por medio de un video, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios