1
Sep
2012

Leer un archivo en C a un array de chars (char*)

En este sencillo código vamos a mostrar y comentar una técnica para leer un archivo (eventualmente binario) a un array de chars (char*) desde C, utilizando algunas system calls POSIX y alguna función de la biblioteca estándar.

/*
Auth: martin.com.uy/sec
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
 
int main(int argc, char* argv[]) {
 
	puts("Comienzo del programa...\n");
 
	int archivo_fd, archivo_open_flags;
 
	archivo_open_flags = O_RDONLY;
 
	archivo_fd = open("/ruta/al/archivo.bin", archivo_open_flags);
 
	if(archivo_fd == -1){
		puts("Error al abrir el archivo.\n");
		return EXIT_FAILURE;
	}
	puts("Archivo abierto correctamente.\n");
 
	puts("Leyendo archivo...\n");
 
	int bytes_leidos;
 
	int cantidad_bytes_archivo = 0;
 
	int comienzo_del_archivo = lseek(archivo_fd, 0, SEEK_SET);
 
	int fin_del_archivo = lseek(archivo_fd, 0, SEEK_END);
 
	printf("Comienzo del archivo offset: %d, Fin del archivo offset: %d.\n\n", comienzo_del_archivo, fin_del_archivo);
 
	cantidad_bytes_archivo = fin_del_archivo - comienzo_del_archivo;
 
	char* archivo_bytes = (char*)malloc(cantidad_bytes_archivo);
 
	lseek(archivo_fd, 0, SEEK_SET);
 
        read(archivo_fd, archivo_bytes, cantidad_bytes_archivo);
 
	printf("Lectura del archivo finalizada. Cantidad de bytes archivo: %d.\n\n", cantidad_bytes_archivo);
 
	if(close(archivo_fd) == -1){
		puts("Error al cerrar el archivo.\n");
		return EXIT_FAILURE;
	}
 
	puts("Archivo cerrado.\n");
 
	return EXIT_SUCCESS;
}

Si bien el código es auto-explicativo, quiero comentar brevemente lo que se está haciendo en la parte central de la función.

Una vez abierto el archivo (obtenido su file descriptor), el kernel almacena un offset donde se indica la posición en la que estamos parados sobre el archivo. Cada vez que utilizamos, por ejemplo, la system call read(), este offset es incrementado la cantidad de bytes que hayan sido leídos -hasta llegar al EoF-.

La system call lseek() nos permite controlar (mover) este offset donde estamos parados dentro del archivo abierto. Lo que hacemos en esta función es pararnos al principio, pararnos al final y obtener el largo del archivo en bytes. Una vez con ese largo, construimos un buffer de lectura del tamaño exacto del archivo. Con dicho buffer utilizamos la system call read() y de una sola vez cargamos el archivo.

Probablemente esta forma de leer sea más útil para archivo binarios.

Escribir un comentario