Ejemplos java y C/linux

Tutoriales

Enlaces

Licencia

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.
Para reconocer la autoría debes poner el enlace https://old.chuidiang.org

Leer y Escribir un fichero de texto

En java tenemos muchas posibilidades para leer y escribir ficheros de texto, binarios, con formato xml, etc, etc. En este tutorial nos vamos a centrar en escribir y leer ficheros de texto llano. Vermos también la clase JFileChooser que permite mostar una ventana para que el usuario navegue por los directorios y elija un fichero. No nos meteremos en profunidades, sólo lo básico para empezar a escribir y leer ficheros.

La clase JFileChooser

Siguiendo con nuestro editor de textos sencillo, dos de las acciones que debemos implementar en nuestro menú son las de salvar el texto en fichero y leer el texto de un fichero. En ambos casos hay que darle oportunidad al usuario de elegir el fichero bien para salvar, bien para leer.

La clase JFileChooser muestra directamente una ventana que permite navegar por los directorios y elegir un fichero. Un uso simple de esta clase es realmente sencillo.

Para pedir un fichero para abrirlo y leerlo basta hacer dos líneas de código

JFileChooser fileChooser = new JFileChooser();
int seleccion = fileChooser.showOpenDialog(areaTexto);

Veremos el parámetro areaTexto un poco más abajo. Por lo demás, listo, esto abre una ventana para navegar por los directorios y elegir un fichero similar a la de la figura

JFileChooser

Cuando el usuario termine, pulsará "Abrir" o "Cancelar". En el entero seleccion se nos guardará el botón que ha apretado. Sólo debemos comprobar si es el botón de "Abrir" para pedirle al JFileChooser qué fichero ha elegido el usuario y empezar a trabajar con él.

if (seleccion == JFileChooser.APPROVE_OPTION)
{
   File fichero = fileChooser.getSelectedFile();
   // y a trabajar con fichero ....
}

Si seleccion vale JFileChooser.APPROVE_OPTION es que el usuario ha pulsado "Abrir", así que pedimos el fichero seleccionado con getSelectedFile() y ... ¡¡¡ a trabajar !!!

Vale, vale, pero ¿qué es eso de pasarle el areaTexto en el parámetro?. La explicación es simple. JFileChooser abre una ventana que se mostrará junto a la ventana de nuestro editor. Nos gustaría que esta ventana de selección de fichero no se vaya detrás y quede oculta por la ventana del editor. La ventana de elegir fichero debería estar siempre delante y visible sobre el editor. La forma de conseguir esto es que JFileChooser sepa cual es esta ventana delante de la cual debe estar siempre. Para saber cual es esa ventana, basta con pasarle en el parámetro cualquier componente de dicha ventana. En nuestro ejemplo hemos decidido pasarle el JTextArea de nuestro editor, pero podíamos pasarle perfectamente el JMenuBar o el JFrame principal.

El JTextArea es una buena elección por un segundo motivo. Este código estará en las acciones de salvar y cargar texto de un fichero. El texto que se va a guardar o el que se lea se cojerá o meterá en el JTextArea. La clase AccionSalvar y AccionCargar deben tener accesible el JTextArea para leer de él el texto que tienen que guardar en fichero o para meter en él el texto que han leido del fichero. Puesto que tienen que tener el JTextArea de todas maneras, lo usaremos como parámetro del JFileChooser.

Para elegir un fichero para salvar, el código es exactamente igual, pero cambia el método para visualizar el diálogo.

JFileChooser fileChooser = new JFileChooser();
int seleccion = fileChooser.showSaveDialog(areaTexto);

La única diferencia es que cambia la etiqueta del botón "Abrir" por "Guardar".

Escribir un fichero de texto

Una vez elegido el fichero en el que queremos salvar el texto, simplemente debemos abrir el fichero para escritura y emepezar a escribir.

En java tenemos muchas clases y variantes para escribir ficheros: PrintStream, FileWriter, FileOutputStream, etc, etc. Todas hacen lo mismo, escribir en un fichero. La diferencia entre ellas suelen ser los métodos que tienen para escribir en el fichero o algunos aspectos internos, como si usan buffer o no. Algunas de ellas sólo tienen métodos para escribir bytes, otras permiten escribir String, etc, etc. Para elegir una de ellas, simplemente hay que ver qué tenemos, un File en nuestro caso y qué necesitamos, en nuestro caso algún método que nos permita escribir String.

Por supuesto, esta forma de elegir es muy tonta, pero nos vale para nuestro ejemplo. Si queremos "darle caña" al fichero escribiendo mucho y muy seguido quizás sea mejor pensar en qué clases son más eficientes en vez de en limitarnos a si tiene o no un método que nos resulte cómodo. Sin embargo, esto es tema para otro tutorial.

Para escribir fichero de texto llano a partir de un File, que es el que nos proporciona la clase JFileChooser, una clase ideal es PrintWriter. Simplemente con el siguiente código tenemos todo hecho

PrintWriter writer = new PrintWriter(fichero);
writer.print(areaTexto.getText());
writer.close();

Abrimos el fichero haciendo un new PrintWriter(), con print() escribimos el texto obtenido de areaTexto.getText() y cerramos el fichero.

PrintWriter tiene además muchos métodos que permiten escribir en formato texto llano números, cadenas, etc.

Leer un fichero

Para leer un fichero nos pasa algo parecido. Tenemos un montón de clases que leen ficheros FileInputStream, FileReader, InputStreamReader, BufferedReader. Igual que al escribir, es ver qué tenemos, un File, qué métodos queremos, alguno que nos permita leer String y elegir la clase que nos interese.

En el caso de la lectura es un poco más complejo. No hay una clase que admita File y tenga métodos para leer String. Mirando la API, vemos que el método readLine() que nos interesa y que es capaz de leer una línea y dárnosla como String está en la clase BufferedReader. Desgraciadamente esta clase admite en su constructor un Reader y no un File que es lo que tenemos. El asunto se nos complica un poco. Debemos buscar una clase que herede de Reader y que admita un File. Buscando, buscando, encontramos que FileReader cumple con estos requisitos.

Bueno, construir el BufferedReader es algo más complejo

BufferedReader reader = new BufferedReader(new FileReader(fichero));

BufferedReader va leyendo de línea en línea. No lee los retornos de carro. Debemos hacer un bucle para ir leyendo. Puede ser similar a este

String linea = reader.readLine();
while (linea != null)
{
   // Aquí lo que tengamos que hacer con la línea puede ser esto
   areaTexto.append(linea);
   linea = reader.readLine();
}

Si hacemos esto y miramos el resultado nos llevamos el primer chasco. Salen todas las líneas seguidas, no sale cada línea en una línea. El problema es que readLine() nos devuelve la línea, pero sin el retorno de carro al final. Si vamos añadiendo en el area de texto, debemos añadir nosotros desde nuestro código los retornos de carro.

¿Cual es el retorno de carro?. En windows el retorno de carro consiste en dos caracteres seguidos /r/n. En unix el retorno de carro sólo es uno /n. ¿Qué ponemos para que nuestro programa siga siendo portable?. La clase System de java nos permite consultar este tipo de cosas. Si ponemos

String retornoDeCarro = System.getProperty("line.separator");

en retornoCarro obtendremos el retorno de carro adecuado para nuestro sistema operativo. En System.getProperties() de la API puedes ver una lista de cosas interesantes que se pueden obtener, como el nombre del sistema operativo, el directorio actual de ejecución o el nombre del usuario.

Nuestro código quedaría así

String linea = reader.readLine();
while (linea != null)
{
   // Aquí lo que tengamos que hacer con la línea puede ser esto
   areaTexto.append(linea);
   areaTexto.append(System.getProperty("line.separator"));
   linea = reader.readLine();
}

Por supuesto, no se nos debe olvidar cerrar el fichero cuando terminemos

reader.close();

La clase StringBuffer

En el ejemplo hemos ido componiendo el texto directamente sobre el area de texto, usando su método append().

Otra opción es componer el texto directamente sobre un String y luego añadirlo todo de golpe. El código quedaría más o menos así

String lineaTotal="";
String linea = reader.readLine();
while (linea != null)
{
   lineaTotal = lineaTotal + linea + System.getProperty("line.separator");
   linea = reader.readLine();
}
areaTexto.setText(lineaTotal);
reader.close();

Esta opción es válida, pero no es eficiente. Se crean demasiadas clases String intermedias que se dejan luego para el recolector de basura. Para este tipo de cosas, java tiene la clase StringBuffer. Es básicamente un String, pero que permite ser modificado, añadiendo y borrando cosas de forma eficiente.

El código con esta clase quedaría así

StringBuffer lineaTotal="";
String linea = reader.readLine();
while (linea != null)
{
   lineaTotal.append(linea);
   lineaTotal.append(System.getProperty("line.separator"));
   linea = reader.readLine();
}
areaTexto.setText(lineaTotal.toString());
reader.close();

Listo por ahora. Vamos a ver cómo buscar y seleccionar texto en el JTextArea.

Estadísticas y comentarios

Numero de visitas desde el 4 Feb 2007:

Aviso Legal