Sesión 12: Ficheros de texto y ficheros binarios
- En este laboratorio vamos a trabajar con ficheros de texto y ficheros binarios en C.
- Déjame empezar con un par de preguntas:
- ¿Qué es un fichero?
- ¿Qué diferencia un fichero binario de un fichero de texto?
- Los ficheros de texto son ideales para almacenar información de manera legible para los humanos, pero a menudo son menos eficientes en términos de espacio y acceso.
- Los ficheros binarios, en cambio, permiten almacenar datos en su representación interna, ahorrando espacio y mejorando el rendimiento, pero son menos legibles para los humanos.
Playlists
- Usaremos como ejemplo una playlist de canciones, donde cada canción tendrá:
- Título (cadena de caracteres)
- Artista (cadena de caracteres)
- Duración (en segundos, entero)
- Valoración (entero de 1 a 5)
Playlist como fichero de texto
- Un fichero de texto almacena datos como cadenas legibles por humanos, separadas por delimitadores como espacios, comas, saltos de línea, etc. Por ejemplo (hits de 2024, pon los tuyos :)):
|
|
- Escribe un programa que abra y lea un fichero con ese formato, las guarde en un array, lo ordene por valoración (de mayor a menor) e imprima la playlist ordenada en la salida estándar siguiendo el mismo formato
- Atención:
- Si hay un error al abrir el fichero o al reservar memoria puedes
usar la función
perror
(man 3 perror
) antes de terminar tu programa con exit status distinto de 0 - No sabes el número de canciones a priori (tendrás que pedir
memoria: puedes pedir espacio para 5 canciones y si te hace falta
más pedir más con
realloc
, necesitarás el número de canciones que llevas metias en tu array) - Las comillas no forman parte de los nombres de los artistas ni de las canciones, sólo están ahí para hacer más agradable el texto para los humanos
- Puedes asumir que los nombres de los artistas y canciones no superan los 100 caracters
- Representa las canciones usando
struct
- Si hay un error al abrir el fichero o al reservar memoria puedes
usar la función
- Reflexiones:
- ¿Cómo de fácil es editar el fichero de texto?
- ¿Cómo de fácil es parsearlo por un programa? (to parse es un verbo en inglés que significa analizar y procesar sintácticamente un texto)
- ¿Cuántos caracteres tiene la canción “Automático”? ¿Qué dice
strlen
? ¿Qué caracteres tiene? ¿Qué bytes?
Playlist como fichero de binario
- Un fichero binario almacena datos en su forma interna (binaria), haciendo que ocupe menos espacio y que su acceso sea más rápido. Sin embargo, los datos no son directamente legibles por humanos
- Por ejemplo, la duración 225, en vez de guardarla con tres
caracteres
2
,2
y5
, y por lo tanto como tres bytes 50, 50 y 53 se podría guardar como un único byte 225 (¡que como texto es el caracterá
!) - Modifica el programa anterior para escribir la playlist ordenada
en formato binario (si el fichero que lees es
playlist.txt
el que escribas puedes llamarloplaylist.bin
) - Atención:
- Puedes usar la función
fwrite
(man 3 fwrite
) para escribir una zona de memoria contigua en un fichero byte a byte, eso provoca que tu fichero sea binario - A la hora de abrir el fichero (
fopen
) tienes que indicar el modo de apertura: lectura (“r”), escritura (“w”), etc. Pero además puedes indicar si el modo es binario (“b”). En el manual puedes leer esto:
- Puedes usar la función
|
|
- Reflexiones:
- ¿Se puede editar un fichero binario? ¿Qué implicaciones tiene?
- ¿Cómo de fácil es parsearlo por un programa?
- ¿Crees que para tu programa hay alguna diferencia entre abrir un fichero en modo texto o en modo binario?
Leyendo un fichero binario
- Escribe un programa que lea una fichero binario que contiene una playlist y que imprima la playlist en la salida estándar siguiendo el formato textual legible para humanos
- Atención:
- Usa la función
fread
(man 3 fread
) simétrica defwrite
para leer las canciones del fichero binario - Puedes leerlas de 1 en 1, de 5 en 5, como quieras, pero recuerda
que aquí tampoco conoces el número de canciones en el fichero
(¿aunque quizás podrías calcularlo fácilmente (mira las funciones
fseek
,ftell
y la constanteSEEK_END
enstdio.h
)?)
- Usa la función