I/O y NIO - Navegación de archivos y I/O (1/7)
NIO es el "Nuevo I/O" que contiene paquetes nuevos desde Java 1.4. Actualmente hay un NIO.2, o sea, paquetes más nuevos aún, que aparece en Java 7. Para generalizar, cuando se mencione NIO, se estará tratando de NIO2.
En este post veremos algunos ejemplos sobre estos paquetes que son muy útiles, y también necesarios para el examen de certificación.
Creación de un archivo
package com.apuntesdejava.ionio; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class Ejemplo01 { private static final Logger LOG = Logger.getLogger(Ejemplo01.class.getName()); public static void main(String[] args) { try { //Se crea una referenia a un archivo, pero no existe aún File file = new File("archivo01.txt"); //A ver, ¿existe? System.out.println("Existe:" + file.exists());//la primera vez, no //tratamos de crearlo... boolean newFile = file.createNewFile(); //devuelve TRUE si logró crearlo porque no existía //a ver.. System.out.println("Se creo el archivo:"+newFile); //y existe??? System.out.println("Existe 2:" + file.exists());//la primera vez, no } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } } }
Bastante simple... hasta ahora.
Escribir y Leer contenido de un archivo
Ahora, hagamos un programa que pueda escribir un contenido en un archivo creado.package com.apuntesdejava.ionio; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class ReaderWritter { private static final Logger LOG = Logger.getLogger(ReaderWritter.class.getName()); public static void main(String[] args) { //Nuevo archivo de pruebas File file = new File("archivo02.txt"); //Creamos un objeto para escribir caracteres en el archivo de prueba try (FileWriter fw = new FileWriter(file)) { fw.write("Hola todos\nsaludos desde el espacio\n"); //Este es el contenido } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } //Ahora leeremos el contenido try (FileReader fr = new FileReader(file)) { //tenemos nuestro espacio para leer el contenido char[] buffer = new char[100]; //... y al leerlo, guardamos el tamanio leiodo int tamanio = fr.read(buffer); System.out.println("Tamaño del contenido:" + tamanio); //Escribimos el contenido System.out.println("Contenido:"); for (char c : buffer) { System.out.print(c); //caracter por caracter } } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } } }
En la siguiente tabla veremos un pequeño api de las clases y métodos más importantes para
java.io
Clase | Heredado de | Argumentos de los constructores importantes | Métodos importantes | |
---|---|---|---|---|
File |
Object |
File, String String String, String
|
createNewFile() delete() isDirectory() isFile() list() mkdir() renameTo()
|
|
FileWriter |
Writer |
File String
|
close() flush() write()
|
|
BufferedWriter |
Writer |
Writer
|
close() flush() newLine() write()
|
|
PrintWriter |
Writer |
File String OutputStream Writer
|
close() flush() format(), printf() print(), println() write()
|
|
FileReader |
Reader |
File String
|
read()
|
|
BufferedReader |
Reader |
Reader
|
read() readLine()
|
Si revisamos un poco la tabla, podemos notar que si queremos leer de archivo con texto plano (usando el método
readLine
) solo está en la clase BufferedReader
.... pero este no tiene un constructor con el nombre del archivo como argumento. Entonces ¿cómo leo el archivo?. Aquí es donde debemos juntar con otras clases.
private static final Logger LOG = Logger.getLogger(BufferedReaderTest.class.getName()); public static void main(String[] args) { String nombreArchivo = "archivo03.txt"; //vamos a crear un archivo para escribir en él try (PrintWriter pw = new PrintWriter(nombreArchivo)) { pw.println("Este es un texto de ejemplo"); } catch (FileNotFoundException ex) { LOG.log(Level.SEVERE, null, ex); } //ahora, vamos a leerlo try (FileReader fr = new FileReader(nombreArchivo)) { BufferedReader br = new BufferedReader(fr); String linea; //leer hasta que sea null, que es el fin de archivo while ((linea = br.readLine()) != null) { LOG.info(linea);//imprimir el contenido en pantalla } } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } }
En la línea 35 podemos ver que se creará un objeto de
FileReader
utilizando el nombre del archivo dado en un String
, y en la línea 36 se utiliza este objeto para la creación de un objeto de tipo BufferedReader
. A partir de aquí ya se puede leer el contenido de manera natural.
Manejando archivos y carpetas (directorios)
La clasejava.io.File
permite manejar tanto archivos como carpetas. Adicionalmente, sus métodos pueden ser usados para borrar archivos, renombrarlos, saber si existe el archivo, crear archivos temporales, cambiar atributos del archivo y determinar si es un archivo o una carpeta. La confusión sucede cuando un objeto de tipo java.io.File
es usado para representar o un archivo o una carpeta. Por ejemplo, si creamos un objeto así:
File file = new File("algo");
... pueden suceder dos cosas:
- Si "algo" no existe, ningún archivo es creado
- Si "algo" existe, el objeto referenciado
file
apunta a un archivo existente.
file = new File("algo");
NUNCA crea un archivo.Existen dos maneras de crear un archivo.
1. Invocando al método
createNewFile()
del objeto java.io.File
.
File file = new File("algo"); //Archivo aún no creado file.createNewFile(); //Crea un archivo llamado "algo" apuntado por 'file'
2. Creando una instancia de
Writer
o Stream
. Específicamente, instanciar un FileWriter
, PrintWriter
o FileOutputStream
. De cualquier manera, se creará el archivo ni bien es instanciado. Por ejemplo:File file = new File("algo"); //Archivo aún no creado PrintWriter pw = new PrintWriter(file); //Se instancia 'pw' de tipo 'PrintWriter' //y apunta al archivo 'algo' asignado por 'file'.
Crear una carpeta (o directorio) es similar al de un archivo.
File miDir = new File("mi_directorio"); // crea un objeto miDir.mkdir(); // crea la carpeta con el nombre // descrito en el objeto 'miDir' //una vez creada la carpeta, se puede crear un archivo File miArchivo = new File(miDir,"archivo04.txt"); //el primer argumento es el //directorio donde estará el archivo miArchivo.createNewFile();
Ojo, si no se crea la carpeta (línea 2 del código anterior) al momento de crear el archivo (línea 7), lanzará una excepción
Además de crear archivos, la clase
java.io.File
hace otras cosas como renombrar y borrar archivos. El siguiente código muestra un poco de estos métodos. Notar las líneas resaltadas.
public class DeleteRenameFilesTest { private static final Logger LOG = Logger.getLogger(DeleteRenameFilesTest.class.getName()); public static void main(String[] args) { try { File dir0 = new File("dir0"); //haciendo un directorio File dir1 = new File(dir0, "dir1");//haciendo un subdirectorio dir1.mkdirs(); //con esto se crean todas las carpetas necesarias File file1 = new File(dir1, "file1.txt"); //creando un archivo file1.createNewFile(); File file2 = new File(dir0, "file2.txt");//creando otro archivo file2.createNewFile(); //tratando de borrar el directorio 'dir0'... LOG.log(Level.INFO, "Borrando el directorio {0}:{1}", new Object[]{dir0, dir0.delete()}); //... pero no va a poder porque tiene contenido. Debe estar vacío File file3 = new File(dir0, "file3.txt");//otro objeto file1.renameTo(file3); //.. lo renombramos (o movemos) //Tratando de borrar el directorio 'dir1'... LOG.log(Level.INFO, "Borrando el directorio {0}:{1}", new Object[]{dir1, dir1.delete()}); //... y lo logra, porque el archivo ya fue movido File dir2 = new File("nuevo_dir");//renombramos el directorio... LOG.log(Level.INFO, "Renombrando el directorio {0} a {1}: {2}", new Object[]{dir0, dir2, dir0.renameTo(dir2)}); //... y mantendrá el contenido //La primera vez lo hará, pero la segunda no, porque ya existe } catch (IOException ex) { LOG.log(Level.SEVERE, null, ex); } } }
La clase java.io.Console
Esta clase apareción en Java 6. En el contexto común, la consola es un dispositivo físico con un teclado y una pantalla (como una PC o una MAC). Si estamos ejecutando Java SE 6 desde la línea de comandos, ya estamos accediendo al objeto de la consola, el cual está referenciando invocando al método System.console()
. Recordemos que es posible ejecutar nuestros programas Java en un entorno que no tenga acceso al objeto de la consola, y cuando se invoca al método System.console()
, este retornará null
. ¿Como en qué situación? Por ejemplo, en la ventana "Output" del IDE: esa ventana no tiene entrada de teclado.La clase Console hace que sea más fácil la entrada de datos desde la línea de comando, tanto para entradas con eco o sin eco (como los password), y también hace que sea más fácil escribir textos formateados a la línea de comandos. Esto es bastante útil cuando se quiere trabajar con pruebas que no necesite interfaz gráfica (GUI). Veamos un ejemplo bastante explicado.
public class ClaseConsole { public static void main(String[] args) { String nombre = ""; Console c = System.console(); //obtiendo un Console char[] pass; pass = c.readPassword("%s", "Escriba contraseña:"); //devuelve un char[] for (char chr : pass) { c.format("%c", chr); //salida con formato } c.format("\n"); //probamos la entrada de texto while (true) { nombre = c.readLine("%s", "Escribe algo:"); //devuelve un objeto c.format("\tsalida: %s\n", nombre); } } }
Para salir, presionar Ctrl+C
La salida sería esta:
تعليقات
إرسال تعليق
Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups
Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/