Unidad 6. Almacenando Datos
Unidad 6. Almacenando Datos
Unidad 6. Almacenando Datos
AVISO: Esta página ha sido generada para facilitar la impresión de los contenidos. Los enlaces externos a
otras páginas no serán funcionales.
Almacenando datos.
Caso práctico
Ada está repasando los requisitos de la aplicación
informática que están desarrollando para la clínica
veterinaria.
Precisamente Antonio, que cada vez está más entusiasmado con la idea de
estudiar algún ciclo, de momento, está matriculado y cursando el módulo de
Programación, y está repasando para el examen que tiene la semana que viene,
uno de los temas que le "cae" es precisamente el de almacenamiento de
información en ficheros.
1.- Introducción.
Cuando desarrollas programas, en la mayoría de ellos los usuarios
pueden pedirle a la aplicación que realice cosas y pueda
suministrarle datos con los que se quiere hacer algo. Una vez
introducidos los datos y las órdenes, se espera que el programa
manipule de alguna forma esos datos, para proporcionar una
respuesta a lo solicitado.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 1/32
2/2/2014 eXe
Por tanto, sabemos que el almacenamiento en variables o vectores (arrays) es temporal, los
datos se pierden en las variables cuando están fuera de su ámbito o cuando el programa
termina. Las computadoras utilizan ficheros para guardar los datos, incluso después de que
el programa termine su ejecución. Se suele denominar a los datos que se guardan en
ficheros datos persistentes, porque existen, persisten más allá de la ejecución de la
aplicación. Los ordenadores almacenan los ficheros en unidades de almacenamiento
secundario como discos duros, discos ópticos, etc. En esta unidad veremos cómo hacer
con Java estas operaciones de crear, actualizar y procesar ficheros.
A todas estas operaciones, que constituyen un flujo de información del programa con el
exterior, se les conoce como Entrada/Salida (E/S).
Distinguimos dos tipos de E/S: la E/S estándar que se realiza con el terminal del usuario y la
E/S a través de ficheros, en la que se trabaja con ficheros de disco.
Todas las operaciones de E/S en Java vienen proporcionadas por el paquete estándar del
API de Java denominado java.io que incorpora interfaces, clases y excepciones para
acceder a todo tipo de ficheros.
Entrada y Salida.
1.1.- Excepciones.
Cuando se trabaja con archivos, es normal que pueda haber
errores, por ejemplo: podríamos intentar leer un archivo que no
existe, o podríamos intentar escribir en un archivo para el que
no tenemos permisos de escritura. Para manejar todos estos
errores debemos utilizar excepciones. Las dos excepciones
más comunes al manejar archivos son:
Autoevaluación
Señala la opción correcta:
Java no ofrece soporte para excepciones.
Un campo y un archivo es lo mismo.
Si se intenta abrir un archivo que no existe, entonces saltará una
excepción.
Ninguna es correcta.
Excepciones en Java.
Caso práctico
Antonio está estudiando un poco antes de irse a dormir. Se ha tomado un vaso
de leche con cacao y está repasando el concepto de flujo. Entenderlo al
principio, cuando lo estudió por primera vez, le costó un poco, pero ya lo
entiende a la perfección y piensa que si le sale alguna pregunta en el examen de
la semana que viene, sobre esto, seguro que la va a acertar.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 3/32
2/2/2014 eXe
Un flujo es una abstracción de aquello que produzca o consuma información. Es una entidad
lógica.
Las clases y métodos de E/S que necesitamos emplear son las mismas
independientemente del dispositivo con el que estemos actuando, luego, el núcleo de Java,
sabrá si tiene que tratar con el teclado, el monitor, un sistema de archivos o un socket de red
liberando al programador de tener que saber con quién está interactuando.
En resumen, será el flujo el que tenga que comunicarse con el sistema operativo concreto y
"entendérselas" con él. De esta manera, no tenemos que cambiar absolutamente nada en
nuestra aplicación, que va a ser independiente tanto de los dispositivos físicos de
almacenamiento como del sistema operativo sobre el que se ejecuta. Esto es primordial en
un lenguaje multiplataforma y tan altamente portable como Java.
Autoevaluación
Señala la opción correcta:
La clase Stream puede representar, al instanciarse, a un archivo.
Si programamos en Java, hay que tener en cuenta el sistema operativo
cuando tratemos con flujos, pues varía su tratamiento debido a la
diferencia de plataformas.
La clase keyboard es la clase a utilizar al leer flujos de teclado.
La vinculación de un flujo al dispositivo físico la hace el hardware de la
máquina.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 4/32
2/2/2014 eXe
Caso práctico
Otro aspecto importante que Ada trata con María y Juan, acerca de los ficheros
para la aplicación de la clínica, es el tipo de ficheros a usar. Es decir, deben
estudiar si es conveniente utilizar ficheros para almacenar datos en ficheros de
texto, o si deben utilizar ficheros binarios. María comenta -Quizás debemos usar
los dos tipos de ficheros, dependerá de qué se vaya a guardar, -Juan le contesta
-tienes razón María, pero debemos pensar entonces cómo va el programa a leer
y a escribir la información, tendremos que utilizar las clases Java adecuadas
según los ficheros que decidamos usar.
OutputStream. Estas dos clases son las que definen los métodos que sus subclases
tendrán implementados y, de entre todos, destacan read() y write() que leen y escriben
bytes de datos respectivamente.
Las clases del paquete java.io se pueden ver en la ilustración. Destacamos las clases
relativas a flujos:
Destacar que hay clases que se "montan" sobre otros flujos para modificar la forma de
trabajar con ellos. Por ejemplo, con BufferedInputStream podemos añadir un buffer a un flujo
FileInputStream, de manera que se mejore la eficiencia de los accesos a los dispositivos en
los que se almacena el fichero con el que conecta el flujo.
Debes conocer
En el siguiente vídeo puedes clarificar algunos de estos conceptos.
El método nextToken devuelve un int que indica el tipo de token leído. Hay una serie de
constantes definidas para determinar el tipo de token:
En el código de la clase, apreciamos que se iterará hasta llegar al fin del fichero. Para cada
token, se mira su tipo, y según el tipo se incrementa el contador de palabras o de números.
Autoevaluación
Indica si la siguiente afirmación es verdadera o falsa.
Según el sistema operativo que utilicemos, habrá que utilizar un flujo u otro.
¿Verdadero o Falso?
Verdadero. Falso.
4.- Flujos.
Caso práctico
Ana y Antonio salen de clase. Antonio ha quedado con una amiga y Ana va
camino de casa pensando en lo que le explicaron en clase hace unos días.
Como se quedó con dudas, también le consultó a María. En concreto, le
asaltaban dudas sobre cómo leer y escribir datos por teclado en un programa, y
también varias dudas sobre lectura y escritura de información en ficheros. María
le solventó las dudas hablándole sobre el tema, pero aún así, tenía que probarlo
tranquilamente en casa, haciéndose unos pequeños ejemplos, para comprobar
toda la nueva información aprendida.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 7/32
2/2/2014 eXe
Hemos visto qué es un flujo y que existe un árbol de clases amplio para su manejo. Ahora
vamos a ver en primer lugar los flujos predefinidos, también conocidos como de entrada y
salida, y después veremos los flujos basados en bytes y los flujos basados en carácter.
Acerca de Unicode.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 8/32
2/2/2014 eXe
Java tiene acceso a la entrada/salida estándar a través de la clase System. En concreto, los
tres ficheros que se implementan son:
Stdin. Es un objeto de tipo InputStream, y está definido en la clase System como flujo
de entrada estándar. Por defecto es el teclado, pero puede redirigirse para cada host
o cada usuario, de forma que se corresponda con cualquier otro dispositivo de
entrada.
Stdout. System.out implementa stdout como una instancia de la clase PrintStream. Se
pueden utilizar los métodos print() y println() con cualquier tipo básico Java como
argumento.
Stderr. Es un objeto de tipo PrintStream. Es un flujo de salida definido en la clase
System y representa la salida de error estándar. Por defecto, es el monitor, aunque es
posible redireccionarlo a otro dispositivo de salida.
int System.in.read();
Lee el siguiente byte (char) de la entrada estándar.
int System.in.read(byte[] b);
Leer un conjunto de bytes de la entrada estándar y lo almacena en el vector b.
System.out.print(String);
Muestra el texto en la consola.
System.out.println(String);
Muestra el texto en la consola y seguidamente efectúa un salto de línea.
Normalmente, para leer valores numéricos, lo que se hace es tomar el valor de la entrada
estándar en forma de cadena y entonces usar métodos que permiten transformar el texto a
números (int, float, double, etc.) según se requiera.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 9/32
2/2/2014 eXe
boolean
Convierte una cadena en un valor lógico
Boolean.parseBoolean(String)
Autoevaluación
Señala la opción correcta:
Read es una clase de System que permite leer caracteres.
StringBuffer permite leer y StringBuilder escribir en la salida estándar.
La clase keyboard también permite leer flujos de teclado.
Stderr por defecto dirige al monitor pero se puede direccional a otro
dispositivo.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 10/32
2/2/2014 eXe
Debes conocer
En este vídeo puedes ver un ejemplo sencillo y explicado sobre la gestión de las
excepciones en Java.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 11/32
2/2/2014 eXe
Recomendación
En los enlaces siguientes puedes ver la documentación oficial de Oracle sobre
FileInputStream y sobre FileOutputStream.
FileInputStream. FileOutputStream.
Hay que recordar que cada vez que se llama a un constructor se abre el flujo de datos y es
necesario cerrarlo cuando no lo necesitemos.
Existen muchos tipos de flujos dependiendo de la utilidad que le vayamos a dar a los datos
que extraemos de los dispositivos.
Un flujo puede ser envuelto por otro flujo para tratar el flujo de datos de forma cómoda. Así,
un bufferWriter nos permite manipular el flujo de datos como un buffer, pero si lo envolvemos
en un PrintWriter lo podemos escribir con muchas más funcionalidades adicionales para
diferentes tipos de datos.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 12/32
2/2/2014 eXe
Podemos ver cómo se usa InputStreamReader que es un puente de flujos de bytes a flujos
de caracteres: lee bytes y los decodifica a caracteres. BufferedReader lee texto de un flujo
de entrada de caracteres, permitiendo efectuar una lectura eficiente de caracteres, vectores
y líneas.
Como vemos en el código, usamos FileWriter para flujos de caracteres, pues para datos
binarios se utiliza FileOutputStream.
Autoevaluación
Indica si es verdadera o falsa la siguiente afirmación:
Para flujos de caracteres es mejor usar las clases Reader y Writer en vez de
InputStream y OutputStream.
Verdadero. Falso.
c:\\datos\Programacion\fichero.txt
Para evitar problemas en la ejecución de los programas cuando se ejecuten en uno u otro
sistema operativo, y por tanto persiguiendo que nuestras aplicaciones sean lo más portables
posibles, se recomienda usar en Java: File.separator.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 13/32
2/2/2014 eXe
Podríamos hacer una función que al pasarle una ruta nos devolviera la adecuada según el
separador del sistema actual, del siguiente modo:
Autoevaluación
Indica si es verdadera o falsa la siguiente afirmación.
Cuando trabajamos con fichero en Java, no es necesario capturar las
excepciones, el sistema se ocupa automáticamente de ellas. ¿Verdadero o
Falso?
Verdadero. Falso.
Caso práctico
Juan le comenta a María -Tenemos que programar una copia de seguridad
diaria de los datos del ficheros de texto plano que utiliza el programa para
guardar la información. -Mientras María escucha a Juan, recuerda que para
copias de seguridad, siempre ha comprobado que la mejor opción es utilizar
ficheros secuenciales.
¿Crees que es una buena opción la que piensa María o utilizarías otra en su lugar?
En este apartado vas a ver muchas cosas sobre los ficheros: cómo leer y escribir en ellos,
aunque ya hemos visto algo sobre eso, hablaremos de las formas de acceso a los ficheros:
secuencial o de manera aleatoria.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 14/32
2/2/2014 eXe
Extensión de un archivo.
Aunque ya has visto un ejemplo que usa BufferedReader, insistimos aquí sobre la filosofía
de estas clases, que usan la idea de un buffer.
La idea es que cuando una aplicación necesita leer datos de un fichero, tiene que estar
esperando a que el disco en el que está el fichero le proporcione la información.
Un dispositivo cualquiera de memoria masiva, por muy rápido que sea, es mucho más lento
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 15/32
2/2/2014 eXe
Autoevaluación
Señala si es verdadera o es falsa la siguiente afirmación:
La idea de usar buffers con los ficheros es incrementar los accesos físicos a
disco. ¿Verdadero o falso?{
Verdadero. Falso.
Para archivos de texto, se puede abrir el fichero para leer usando la clase FileReader. Esta
clase nos proporciona métodos para leer caracteres. Cuando nos interese no leer carácter a
carácter, sino leer líneas completas, podemos usar la clase BufferedReader a partir de
FileReader. Lo podemos hacer de la siguiente forma:
FileWriter("c:/fich2.txt",true);
Código Ascii.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 17/32
2/2/2014 eXe
Para leer datos de un fichero binario, Java proporciona la clase FileInputStream. Dicha clase
trabaja con bytes que se leen desde el flujo asociado a un fichero. Aquí puedes ver un
ejemplo comentado.
Para escribir datos a un fichero binario, la clase nos permite usar un fichero para escritura
de bytes en él, es la clase FileOutputStream. La filosofía es la misma que para la lectura de
datos, pero ahora el flujo es en dirección contraria, desde la aplicación que hace de fuente
de datos hasta el fichero, que los consume.
En la siguiente presentación puedes ver un esquema de cómo utilizar buffer para optimizar
la lectura de teclado desde consola, por medio de las envolturas, podemos usar métodos
como readline(), de la clase BufferedReader, que envuelve a un objeto de la clase
InputStreamReader.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 18/32
2/2/2014 eXe
Autoevaluación
Señala si es verdadera o falsa la siguiente afirmación:
Para leer datos desde un fichero codificados en binario empleamos la clase
FileOutputStream. ¿Verdadero o falso?
Verdadero. Falso.
Se dice que un fichero es de acceso directo o de organización directa cuando para acceder
a un registro n cualquiera, no se tiene que pasar por los n-1 registros anteriores. En caso
contrario, estamos hablando de ficheros secuenciales.
Con Java se puede trabajar con ficheros secuenciales y con ficheros de acceso aleatorio.
Autoevaluación
Señala la opción correcta:
Java sólo admite el uso de ficheros aleatorios.
Con los ficheros de acceso aleatorio se puede acceder a un registro
determinado directamente.
Los ficheros secuenciales se deben leer de tres en tres registros.
Todas son falsas.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 19/32
2/2/2014 eXe
Por tanto para buscar información en un fichero secuencial, tendremos que abrir el fichero e
ir leyendo registros hasta encontrar el registro que buscamos.
Autoevaluación
Señala si es verdadera o es falsa la siguiente afirmación:
Para encontrar una información almacenada en la mitad de un fichero
secuencial, podemos acceder directamente a esa posición sin pasar por los
datos anteriores a esa información. ¿Verdadero o Falso?
Verdadero. Falso.
Esta clase permite leer y escribir sobre el fichero, no se necesitan dos clases diferentes.
Hay que especificar el modo de acceso al construir un objeto de esta clase: sólo lectura o
lectura/escritura.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 21/32
2/2/2014 eXe
Autoevaluación
Indica si es verdadera o es falsa la siguiente afirmación:
Para decirle el modo de lectura y escritura a un objeto RandomAccessFile
debemos pasar como parámetro "rw". ¿Verdadero o Falso?
Verdadero. Falso.
Caso práctico
Antonio ha quedado con Ana para estudiar sobre el tema de ficheros. De
camino a la biblioteca, Ana le pregunta a Antonio -¿Crees que los ficheros se
utilizan realmente, o ya están desfasados y sólo se utilizan las bases de datos? -
Antonio tras pensarlo un momento le dice a Ana -Yo creo que sí, piensa en el
mp3 que usas muchas veces, la música va grabada en ese tipo de ficheros.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 22/32
2/2/2014 eXe
Las fotos que haces con tu cámara digital, o con el móvil, se guardan
en ficheros. Así, existe una gran cantidad de ficheros de imagen,
según el método que usen para guardar la información. Por ejemplo,
tenemos los ficheros de extensión: .jpg, .tiff, gif, .bmp, etc.
Los sistemas operativos, como Linux, Windows, etc., están constituidos por un montón de
instrucciones e información que se guarda en ficheros.
El propio código fuente de los lenguajes de programación, como Java, C, etc., se guarda en
ficheros de texto plano la mayoría de veces.
Y por supuesto, se usan mucho actualmente los ficheros XML, que al fin y al cabo son
ficheros de texto plano, pero que siguen una estructura determinada. XML se emplea mucho
para el intercambio de información estructurada entre diferentes plataformas.
Formato mp3.
Autoevaluación
Indica si es verdadera o falsa la siguiente afirmación:
Un fichero .bmp guarda información de música codificada. ¿Verdadero o falso?
Verdadero. Falso.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 23/32
2/2/2014 eXe
Caso práctico
Ana está estudiando en la biblioteca, junto a Antonio. Está repasando lo que le
explicaron en clase sobre las operaciones relativas a ficheros en Java. En
concreto, está mirando lo relativo a crear carpetas o directorios, listar
directorios, borrarlos, operar en definitiva con ellos. Va a repasar ahora en la
biblioteca, para tener claros los conceptos y cuando llegue de vuelta a casa,
probar a compilar algunos ejemplos que a ella misma se le ocurran.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 24/32
2/2/2014 eXe
El archivo correspondiente a un nombre dado podría ser que no existiera, por ello, habrá que
controlar las posibles excepciones.
A través del objeto File, un programa puede examinar los atributos del archivo, cambiar su
nombre, borrarlo o cambiar sus permisos. Dado un objeto file, podemos hacer las siguientes
operaciones con él:
Autoevaluación
Indica si es verdadera o falsa la siguiente afirmación:
Un objeto de la clase File representa un fichero en sí mismo. ¿Verdadero o
falso?
Verdadero. Falso.
Este método devolverá verdadero (true), en el caso de que el fichero cuyo nombre se indica
en el parámetro nombre aparezca en la lista de los ficheros del directorio indicado por el
parámetro dir.
En el siguiente ejemplo vemos cómo se listan los ficheros de la carpeta c:\datos que tengan
la extensión .odt. Usamos try y catch para capturar las posibles excepciones, como que no
exista dicha carpeta.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 26/32
2/2/2014 eXe
Autoevaluación
Indica si la siguiente afirmación es verdadera o falsa:
Una clase que implemente FileNameFilter puede o no implementar el método
accept. ¿Verdadero o Falso?
Verdadero. Falso.
Creamos el objeto que encapsula el fichero, por ejemplo, suponiendo que vamos a
crear un fichero llamado miFichero.txt, en la carpeta C:\\prueba, haríamos:
A partir del objeto File creamos el fichero físicamente, con la siguiente instrucción, que
devuelve un boolean con valor true si se creó correctamente, o false si no se pudo
crear:
fichero.createNewFile()
Para borrar un fichero, podemos usar la clase File, comprobando previamente si existe, del
siguiente modo:
fichero.delete();
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 27/32
2/2/2014 eXe
Para borrar un directorio con Java tenemos que borrar cada uno de los ficheros y directorios
que éste contenga. Al poder almacenar otros directorios, se podría recorrer recursivamente
el directorio para ir borrando todos los ficheros.
Caso práctico
Para la aplicación de la clínica veterinaria María le propone a Juan emplear un
fichero para guardar los datos de los clientes de la clínica. -Como vamos a
guardar datos de la clase Cliente, tendremos que serializar los datos.
Todos los tipos primitivos en Java son serializables por defecto. (Al igual que los arrays y
otros muchos tipos estándar).
Para leer y escribir objetos serializables a un stream se utilizan las clases java:
ObjectInputStream y ObjectOutputStream.
En el siguiente ejemplo se puede ver cómo leer un objeto serializado que se guardó antes.
En este caso, se trata de un String serializado:
Así vemos que readObject lee un objeto desde el flujo de entrada fich. Cuando se leen
objetos desde un flujo, se debe tener en cuenta qué tipo de objetos se esperan en el flujo, y
se han de leer en el mismo orden en que se guardaron.
Autoevaluación
Indica si es verdadera o falsa la siguiente afirmación:
Para serializar un fichero basta con implementar el interface Serializable.
¿Verdadero o falso?
Verdadero. Falso.
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 29/32
2/2/2014 eXe
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 30/32
2/2/2014 eXe
Autoría: David.nikonvscanon.
Licencia: CC-by.
Procedencia:
http://www.flickr.com/photos/nikonvscanon/2081397439/
Autoría: Macglee.
Licencia: CC-by-sa.
Procedencia:
http://www.flickr.com/photos/macglee/4795368373/
Autoría: Paulnasca
Licencia: Dominio público.
Procedencia:
http://es.wikipedia.org/wiki/Archivo:Binary_file.png
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 31/32
2/2/2014 eXe
Autoría: Paubou.
Licencia: CC-by-nc-sa.
Procedencia:
http://www.flickr.com/photos/paubou/2516489783/
http://aulavirtual.educa.jccm.es/Aula_Virtual/blocks/recopila/view.php?id=121433 32/32