PDF. Acceso A Datos. Tema 1
PDF. Acceso A Datos. Tema 1
PDF. Acceso A Datos. Tema 1
Introducción al
manejo de ficheros
01
/ 1. Introducción y contextualización práctica 4
/ 9. Webgrafía 14
© MEDAC
Reservados todos los derechos. Queda rigurosamente prohibida, sin la autorización escrita de los titulares del copyright,
bajo las sanciones establecidas en las leyes, la reproducción, transmisión y distribución total o parcial de esta obra por
cualquier medio o procedimiento, incluidos la reprografía y el tratamiento informático.
Conocer distintas clases para el manejo de ficheros.
Como veremos, una práctica muy común será realizar la descarga de uno o
varios ficheros con el objetivo de manipularlos, es decir, simplemente coger
parte de información y moverla.
• De texto (ASCII): en su interior encontraremos líneas de texto organizadas en código ASCII. Algunos de
los ejemplos son: archivos de aplicaciones de ofimática, archivos de programas de los distintos lenguajes de
programación, ficheros de imágenes, de video, etc.
• Binarios: aquellos ficheros cuya información está representada en código binario. Para poder leer dichos
ficheros, antes debemos saber cómo fueron escritos para escoger la misma lógica en su lectura. Algunos son
.bin, .dat… entre otros.
Una vez instanciado el objeto podremos también crear dicho fichero, para ello usaremos la siguiente línea:
Por último, otra acción básica que deberemos de aprender para el uso y gestión de ficheros en Java es la eliminación
de ficheros y directorios, usaremos la siguiente línea:
Para poder mover un fichero, lo primero de lo que hay que asegurarse, es que éste debe de existir. Por otra parte, al
cargar la ruta del fichero origen “fileOrigen” y ejecutar el método renameTo(), debemos indicar al método, el fichero
destino “fileDestino”. Hay que tener en cuenta que la ruta destino debe de ser una ruta operativa y existente.
Método Descripción
• Acceso secuencial.
Previamente, tendremos que realizar un estudio del aplicativo a desarrollar para saber qué modo de acceso nos
conviene. En el modo secuencial, como su nombre indica, la información de nuestro fichero es una secuencia de
caracteres o bytes, de forma que, para acceder a un determinado byte o carácter del fichero, deberíamos de haber
pasado previamente por todos los anteriores.
Si lo que deseamos es acceder a un registro o posición determinada de nuestro fichero, entonces nuestro método a
escoger será el modo aleatorio.
La diferencia más notable entre estos dos tipos de acceso es la siguiente: mientras los ficheros de acceso secuencial
deberán ser recorridos byte a byte o carácter a carácter con el tiempo, procesado de la información, y uso de
recursos que esto conllevaría, mientras que, en los ficheros de acceso aleatorio o directo, se establecerá un puntero
en bytes, el cual indicará la posición exacta donde vamos a realizar la lectura y/o escritura, y al que se podrá acceder
directamente.
A lo largo de este tema revisaremos las distintas herramientas y clases de las que disponemos para realizar los
distintos métodos de acceso. A continuación, mostramos una tabla orientativa sobre algunas de las clases que
podremos utilizar:
RandomAccessFile RandomAccessFile
Nudo: Juan ha investigado y ha encontrado la paquetería de Java: “java.io”. Duda porque entiende que es la librería
de uso y análisis de ficheros, pero no sabe muy bien qué clase usar.
Desenlace: en este caso, según los requerimientos de Juan deberá escoger la clase “java.io.File”. Esta le permitirá
tanto crear ficheros, como saber su fecha de modificación, y a parte podrá moverlos entre directorios.
TÉCNICO EN DESARROLLO DE APLICACIONES MULTIPLATAFORMAS
/7 MEDAC · Instituto Oficial de Formación Profesional
• createNewFile()
• renameTo()
Para empezar, instanciaremos el objeto de nuestra clase e indicaremos la ruta del fichero a cargar.
Con el método read() estaremos accediendo al primer byte del fichero. Éste devuelve un número entero, por lo
tanto lo asignamos a una variable entera.
TEMA 1. INTRODUCCIÓN AL MANEJO DE FICHEROS
ACCESO A DATOS /8
Una vez obtenido el primer byte, ya podremos trabajar con él. Con este método accedemos al primer Byte del
fichero “en bruto” y nos servirá para leer imágenes o archivos binarios. Finalmente, cerramos el fichero y liberamos
los recursos del sistema que estaban haciendo uso del “stream” de bytes:
A modo aclaración puntualizar que en estos ejemplos se ha suprimido el control de excepciones para mayor limpieza
de código. Más adelante veremos cómo manejarlas.
El modo de acceso secuencial con caracteres, hace posible la lectura y escritura de un fichero a través de un “stream”
de caracteres. Mientras que las clases vistas previamente leen y escriben por medio de Bytes, las que veremos a
continuación lo hacen manipulando directamente caracteres. Estas son: FileReader y FileWritter.
• FileReader (lectura): básicamente esta clase nos facilitará la lectura de los ficheros de caracteres. Pasamos a
ver su utilización:
Como podemos observar, la lógica es muy parecida a la clase vista con anterioridad FileInputStream. No
obstante, ésta la usábamos para obtener los bytes “en bruto” directamente, mientras que la clase FileReader fue
escrita con el propósito de leer flujos o “streams” de caracteres. Para ello, como podemos ver en el ejemplo, justo
antes de mostrar el resultado por pantalla, realizamos un casting (char) para poder visualizar ese primer carácter de
nuestro fichero “pruebas2.txt”
• FileWritter (escritura): con la siguiente clase seremos capaces de escribir ficheros de caracteres:
En la imagen superior podemos observar como instanciamos nuestra clase de escritura en la primera línea de
código, en donde, además, indicamos la ubicación. En el caso que no existiera el fichero, se crearía automáticamente.
Si el fichero existe, será sobrescrito.
En la segunda línea directamente insertamos los caracteres que deseamos incluir en nuestro fichero. Los pasamos
como parámetro del método “write()”.
Por último, cerramos el flujo aplicando el método “close()”, de esta forma liberaremos los recursos del sistema que
han sido ocupados previamente para dicha operación. Una vez cerrado el flujo tendremos la información escrita en
nuestro fichero.
Utilizaremos la clase RandomAcessFile para acceder a ficheros de forma aleatoria. A diferencia de las clases
anteriores, permite abrir un fichero en modo lectura y además en modo lectura-escritura.
Esta clase permite acceder a un lugar determinado de un fichero y a su vez, leer información o escribirla. Veamos en
detalle las distintas funcionalidades que nos ofrece dicha clase.
Modos de acceso:
• “r”: modo lectura (read mode) obtendremos un IOException si utilizamos este modo en métodos de escritura.
• “rwd”: modo de lectura y escritura de forma síncrona. Se escribirán todas las actualizaciones del contenido del
fichero.
• “rws”: modo de lectura y escritura de forma síncrona. Se escribirán todas las actualizaciones del contenido del
fichero pero además, se escribirán los metadatos.
Veamos ahora cómo instanciar este tipo de objeto y algunos de sus métodos:
RandomAccessFile posee dos constructores, en ambos constructores el segundo parámetro es el mismo: el modo de
acceso. Sin embargo, para el primer parámetro tenemos la versión del constructor en la que podemos introducir el
objeto File directamente o, como en el caso de la imagen superior, introducir la ruta del fichero directamente como
String.
Con el método seek() básicamente nos posicionamos en el punto que indiquemos del fichero. Acepta como
parámetro un objeto de tipo “long”
Si usamos el método getFilePointer(), como bien se define, obtendremos como respuesta un tipo long. Este número
es exactamente la posición del puntero en Bytes
Continuamos con nuestra clase RandomAccessFile, a continuación, veremos la forma de leer y escribir un Byte con
esta clase:
Con el método read(), podremos leer un byte directamente de nuestro fichero. Devolverá dicho byte a partir de la
posición actual del puntero. Veámoslo en el siguiente vídeo:
Usaremos el método write() para escribir un Byte. Dicho Byte será escrito en la posición actual donde se encuentre
el puntero. Acepta como parámetro un entero (el byte a escribir). En este caso como podemos observar en la
imagen, insertaremos la letra “D” en el fichero que corresponde a 68 en la codificación de caracteres ASCII.
Una vez escrito el carácter en el fichero la posición del puntero avanzará una posición.
TÉCNICO EN DESARROLLO DE APLICACIONES MULTIPLATAFORMAS
/ 11 MEDAC · Instituto Oficial de Formación Profesional
De la misma forma que hemos realizado una lectura y escritura de un byte, veremos cómo hacerlo de un array de
bytes en los siguientes fragmentos:
Si en lugar de leer un byte, lo que nos interesa realmente es leer una cantidad determinada de bytes, podremos
realizar una implementación del estilo a la imagen superior. En primer lugar, crearemos un array de bytes, en
concreto 1024. A continuación, definimos la posición del puntero y el tamaño de bytes que queremos extraer de
nuestro fichero. Posteriormente, usamos la sentencia read(), en la que en este caso, acepta como primer parámetro
el array de bytes dónde se va a almacenar la información, y como segundo parámetro, el inicio o posición en la que
comenzaremos a leer.
Finalmente, el último parámetro a introducir indica la cantidad de bytes que deseamos extraer. Este método devuelve
un número entero que representa la cantidad de bytes que han sido leídos.
Éste, básicamente es un espacio determinado y temporal que se aloja en memoria para realizar ciertas operaciones.
En las clases que vimos en apartados anteriores, realizábamos operaciones de lectura o escritura capturando
Bytes, sin embargo, con las clases con sufijo Buffered el funcionamiento interno será ligeramente distinto ya que se
almacena en memoria interna bloques de bytes completos (buffer), y como ya bien sabemos, el acceso a memoria
es mucho más rápido que a disco.
Cada vez que agotamos esa información del buffer y se requiere más, se vuelve a volcar otro bloque de bytes a la
memoria (buffer), de esta forma el rendimiento se ve notablemente mejorado.
Nudo: José se encuentra en la tesitura de elegir entre un modo de acceso secuencial y uno aleatorio. No sabe qué
clase elegir y cual le conviene más para su lógica.
Desenlace: en este caso, José deberá elegir un modo secuencial. Así, recorrer todo el fichero y escribir en el otro al
mismo tiempo.
Para esto, podría usar las clases «FileReader» y «FileWritter», ya que son clases creadas con el objetivo de leer y
escribir este tipo de ficheros.
Para trabajar con estas clases en la resolución del caso, básicamente instanciaremos una nueva clase FileReader, con
la cual iremos leyendo byte a byte con el método read(). Este método nos devolverá un byte en forma de número
entero. En este caso , una vez obtenida la información, procederemos a escribir en el fichero usando ese byte de
información mediante el método write(), y pasando como parámetro el byte leído anteriormente.
Tras terminar las operaciones de lectura-escritura (entrada / salida de datos), simplemente tendríamos que tener
en cuenta el uso del método .close(), tanto para nuestra clase de lectura como para la de escritura, para, de este
modo, liberar recursos.
Realizamos un estudio de los diferentes modos de acceso a los ficheros, y vimos la diferencia entre acceder a ficheros
por medio de gestión de Bytes o por medio de modos de acceso orientados a caracteres.
También se han presentado clases de acceso secuencial, y de acceso aleatorio. Hemos podido observar como realizar
las implementaciones de dichas clases y también las ventajas e inconvenientes de usar unas u otras. También se han
estudiado qué clases pueden mejorar el rendimiento de nuestra máquina y ahorrar recursos.
Irene en este caso podrá elegir entre usar como clase de lectura FileInputStream o FileReader. Esta última, será más
recomendable ya que fue diseñada para el manejo de caracteres:
Con dicha clase tendrá la posibilidad de recorrer dicho fichero y contar al mismo tiempo, las apariciones de dicha
letra.
TÉCNICO EN DESARROLLO DE APLICACIONES MULTIPLATAFORMAS
/ 13 MEDAC · Instituto Oficial de Formación Profesional
Una vez recorrido todo el fichero llegaría el momento de la escritura en disco. Para ello y de la misma forma,
tendríamos opción de usar FileOutputStream o FileWriter. Nos quedaremos igualmente con FileWriter por estar
desarrollado y orientado a la escritura de caracteres.
Una vez preparada nuestra clase de escritura. Nuestra compañera Irene ya tiene la cantidad de apariciones
almacenada en memoria, por lo tanto, simplemente tendrá que añadirle un guion, la fecha actual del sistema y
cerrar el documento.
/ 9. Webgrafía
Oracle web oficial:
https://docs.oracle.com/javase/8/docs/api/?java/io