Ordenar un fichero binario que no cabe en memoria en C
Hola, tengo ke hacer un programa en C ke me ordene un fichero binario muy grande ke no cabe de golpe en memoria.
Yo lo he planteado de la siguiente manera:
Recorro el fichero a ordenar, y voy metiendo lo ke va leyendo en un array limitado ke ire fusionando con un fichero auxiliar. Ese array se ira sobreescribiendo (longitud limitada) hasta recorrer el fichero entero. Finalmente tras fusionar todos los arrays con el fichero auxiliar consigo tener el fichero principal ordenado. Ya solo tendria ke renombrar el auxiliar.
Ahora vienen los problemas,cuando cargo el primer array,tras leer los 5 primeros registros(he limitado a 5),no consigo leer el
siguiente registro del fichero para rellenar de nuevo el array(me lee el ultimo registro leido siempre en vez de leer el sexto registro).
Este es el algoritmo:
i=0;
fread(&num,sizeof(int),1,f1); // if(i<5)}nu[i]=num;i++;}else{vuelcoarray(nu,i);i=0}
while(!feof(f1)){
if (i<5){
nu[i]=num;
i++;
}
else {
pos=ftell(f1);
qsort(nu,i,sizeof(int),&cmp);
mezcla(nu,i);
i=0;
}
if(i==0){
fseek(f1,pos*sizeof(int),SEEK_SET)-1;
}
fread(&num,sizeof(int),1,f1);
}
}
void mezcla(int e[],int l){
FILE *f;
FILE *salida;
int numero;
int i=0;
f=fopen("SEGUNDO.DAT","rb");
if(f==NULL){
f=fopen("SEGUNDO.DAT","wb+");;
}
salida=fopen("SALIDA.DAT","wb");
fread(&numero,sizeof(int),1,f);
while(!feof(f) && i<l) {
if (numero==e[i]) {
fwrite(&numero,sizeof(int),1,salida);
fread(&numero,sizeof(int),1,f);
i++;
} else if (numero<e[i]) {
fwrite(&numero,sizeof(int),1,salida);
fread(&numero,sizeof(int),1,f);
} else {
fwrite(&e[i],sizeof(int),1,salida);
i++;
}
}
/*tratamiento de colas */
while(!feof(f)) {
fwrite(&numero,sizeof(int),1,salida);
fread(&numero,sizeof(int),1,f);
}
while (i<l) {
fwrite(&e[i],sizeof(int),1,salida);
i++;
}
fclose(f);
fclose(salida);
fcloseall();
remove ("SEGUNDO.DAT");
if (rename ("SALIDA.DAT","SEGUNDO.DAT")!=0){
fprintf (stderr,"Error: El fichero salidaemp.dat no se a renombrado como empleado.dat");
}
}
A ver si veis algo mal por ke ya no se ke hacer. Saludos
Yo lo he planteado de la siguiente manera:
Recorro el fichero a ordenar, y voy metiendo lo ke va leyendo en un array limitado ke ire fusionando con un fichero auxiliar. Ese array se ira sobreescribiendo (longitud limitada) hasta recorrer el fichero entero. Finalmente tras fusionar todos los arrays con el fichero auxiliar consigo tener el fichero principal ordenado. Ya solo tendria ke renombrar el auxiliar.
Ahora vienen los problemas,cuando cargo el primer array,tras leer los 5 primeros registros(he limitado a 5),no consigo leer el
siguiente registro del fichero para rellenar de nuevo el array(me lee el ultimo registro leido siempre en vez de leer el sexto registro).
Este es el algoritmo:
i=0;
fread(&num,sizeof(int),1,f1); // if(i<5)}nu[i]=num;i++;}else{vuelcoarray(nu,i);i=0}
while(!feof(f1)){
if (i<5){
nu[i]=num;
i++;
}
else {
pos=ftell(f1);
qsort(nu,i,sizeof(int),&cmp);
mezcla(nu,i);
i=0;
}
if(i==0){
fseek(f1,pos*sizeof(int),SEEK_SET)-1;
}
fread(&num,sizeof(int),1,f1);
}
}
void mezcla(int e[],int l){
FILE *f;
FILE *salida;
int numero;
int i=0;
f=fopen("SEGUNDO.DAT","rb");
if(f==NULL){
f=fopen("SEGUNDO.DAT","wb+");;
}
salida=fopen("SALIDA.DAT","wb");
fread(&numero,sizeof(int),1,f);
while(!feof(f) && i<l) {
if (numero==e[i]) {
fwrite(&numero,sizeof(int),1,salida);
fread(&numero,sizeof(int),1,f);
i++;
} else if (numero<e[i]) {
fwrite(&numero,sizeof(int),1,salida);
fread(&numero,sizeof(int),1,f);
} else {
fwrite(&e[i],sizeof(int),1,salida);
i++;
}
}
/*tratamiento de colas */
while(!feof(f)) {
fwrite(&numero,sizeof(int),1,salida);
fread(&numero,sizeof(int),1,f);
}
while (i<l) {
fwrite(&e[i],sizeof(int),1,salida);
i++;
}
fclose(f);
fclose(salida);
fcloseall();
remove ("SEGUNDO.DAT");
if (rename ("SALIDA.DAT","SEGUNDO.DAT")!=0){
fprintf (stderr,"Error: El fichero salidaemp.dat no se a renombrado como empleado.dat");
}
}
A ver si veis algo mal por ke ya no se ke hacer. Saludos
