Professional Documents
Culture Documents
Abrir fichero
Lo primero de todo es abrir el fichero. Eso de abrir no es nada ms que decirle al sistema
operativo que prepare todo lo necesario para trabajar con un fichero concreto. Tendremos que
abrir tanto el fichero que queremos leer como uno nuevo en el que escribiremos la copia del
primero.
Un fichero tradicionalmente puede abrirse en modo texto o modo binario. No hay diferencia
real entre uno y otro, salvo que en un fichero en modo texto se supone que hay fines de lnea
y en un momento dado hay funciones de ficheros que pueden buscarlos. Si se abre en modo
binario, la informacin puede ser de cualquier tipo y las funciones de ficheros no buscarn
fines de lnea. Digo "tradicionalmente" porque en la prctica no hay ninguna diferencia entre
abrirlo de una manera o de otra. Por convencin, si el fichero es de texto legible se abre en
modo texto. Si el fichero no es de texto legible, se abre en modo binario.
La funcin que nos permite abrir un fichero es fopen(). Sus parmetros son:
Nombre del fichero que queremos abrir, con path absoluto o relativo.
Modo de apertura (lo abrimos para leer, para escribir, etc). Si el modo pone b se abre
en binario. Si no lo pone se abre en modo texto. Los posibles modos son:
o
r o rb: Abre el fichero para lectura. El fichero debe existir o tendremos un error.
a o ab. Abre el fichero para aadirle datos al final. Respeta el contenido que
tuviera.
r+, rb+ o r+b. Abre el fichero para lectura y escritura (el + es el que indica que
es para lectura y escritura a la vez). El fichero debe existir y respeta el
contenido, aunque si escribimos algo iremos machacando datos.
w+, wb+ o w+b. Abre el fichero para lectura y escritura. Crea el fichero si no
existe y machaca el contenido si existe.
a+, ab+ o a+b. Abre el fichero para lecturay y escritura. La escritura comenzar
al final del fichero, respetando el contenido.
La funcin fopen() nos devuelve un FILE*. Esto no es ms que un puntero a una estructura
que contiene informacin sobre el fichero recin abierto. Normalmente podemos ignorar esa
informacin, pero debemos hacer dos cosas con ese FILE* devuelto:
Guardarlo, porque es el puntero que requieren las dems funciones para saber sobre
qu fichero escribir o leer. Nos servir, desde el momento que lo abrimos, para
identificar el fichero con el que queremos trabajar.
Para nuestro ejemplo, abriremos el fichero original como lectura y el fichero en el que haremos
la copia como escritura. Puesto que nos da igual si el fichero es de texto o no, lo abriremos
como binario, ya que es ms general (un fichero de texto, con fines de lnea, no es ms que
un caso particular de un fichero binario, que tiene bytes).
#include<stdio.h>
...
FILE*f1,*f2;
/*Aperturadelficherooriginal,paralecturaenbinario*/
f1=fopen("fichero.dat","rb");
if(f1==NULL)
{
perror("Nosepuedeabrirfichero.dat");
return1;
}
/*Aperturadelficherodedestino,paraescrituraenbinario*/
f2=fopen("fichero2.dat","wb");
if(f2==NULL)
{
perror("Nosepuedeabrirfichero2.dat");
return1;
}
Ya est. f1 es el fichero origen y f2 es la copia.
Lectura del fichero binario
Para leer bytes de un fichero, sin importarnos si hay o no fines de lnea, podemos usar la
funcin fread(). Esta funcin tiene los siguientes parmetros
void *ptr. Un puntero a una zona de memoria donde se guardarn los datos leidos del
fichero. Nosotros pasaremos un array que hayamos creado previamente. En este array
nos dejar la funcin los datos que leamos del fichero. El puntero es de tipo void para
indicar que podemos pasar un puntero a cualquier tipo de dato que queramos.
Nosotros pasaremos uno de char *.
size_t size. El tamao en bytes de los datos que vamos a leer. En nuestro caso, como
queremos leer bytes, este valor ser 1.
size_t nitems. Numero de datos que queremos leer. El numero de datos que
queremos leer multiplicado por el tamao en bytes de cada dato, es decir, el nmero
total de bytes a leer, no puede exceder el tamao del array que pasemos como primer
parmetro o tendremos efectos extraos en nuestro programa. Como el array que
crearemos ser de 1000 char, el numero de items maximo que podemos leer de golpe
son 1000 (el tamao del char es 1).
FILE *stream. Recuerdas lo que nos devolva fopen()?. Pues tenemos que ponerlo
aqu.
La funcin fread() devuelve el nmero de elementos leidos, que debera ser igual a nitems.
Si en el fichero hay tantos o ms elementos como los que hemos mandado leer con
nitems, fread() los lee y devuelve nitems.
void *ptr. El puntero a la zona de memoria. Debe estar relleno con los datos que
queramos escribir en el fichero.
size_t size y size_t nitems indican tamao del elemento a escribir (1 en nuestro caso,
ya que usamos char) y cuantos elementos queremos escribir. El nmero de elementos
que queremos escribir son los que realmente hay en ptr, NO el tamao del array ptr.
Puede ser un array muy grande en el que slo hemos rellenado tres elementos, as
que nitems ser tres.
do
{
leidos=fread(buffer,1,1000,f1);
/*Ahorahayquetratarlosdatos,perosihemosllegadoafinal
defichero,NOhaydatosquetratar.Hayqueponerunfiparaeste
caso*/
if(!feof(f1))
{
/*Tratarlosdatosledos*/
...
}
}while(!feof(f1))
En fin, es cuestin de gustos y puedes usar la opcin que ms te guste o cualquier otra que se
te ocurra. Lo importante es saber que hay que hacer al menos una lectura antes de utilizar
feof().
Dije, de todas formas, que no iba a usar feof(). Por qu?. Imagina que hay 10 bytes en el
fichero y slo 10 bytes. Cuando haga esta lectura
leidos=fread(buffer,1,1000,f1);
while(!feof(f1))
{
/*tratarlosdatosleidos*/
}
se leern los 10 bytes y leidos tendr 10. Pero como hemos llegado a final de fichero, feof()
ser cierto. Si me fio de feof() para terminar, no entrar en el bucle y no tratar esos 10 bytes.
En nuestro ejemplo, haremos el bucle mientras leidos sea mayor que 0. Si es cero, se ha
acabado el fichero, si es -1 ha habido algn error.
leidos=fread(buffer,1,1000,f1);
/*Mientrassehayaleidoalgo...*/
while(leidos!=0)
{
/*...meterloenelficherodestino*/
fwrite(buffer,1,leidos,f2);
/*yleersiguientebloque*/
leidos=fread(buffer,1,1000,f1);
}
Cerrar ficheros
Cuando terminamos de usar un fichero, hay que cerrarlo con fclose(FILE *). Unas tonteras
sobre fclose() para que las tengas en cuenta.
Cuando se termina nuestro programa, el sistema operativo cierra todos los ficheros que
tengamos abiertos. En principio, para un programa tonto como este, fclose() puede no
ponerse sin problemas.
Sin embargo, conviene acostumbrarse a ponerlo para no meter la pata en programas ms
grandes y complejos. Hay dos posibles problemas si no se pone fclose().