Copier un fichier quelconque en passant par un tableau

Copier un fichier quelconque en passant par un tableau

fread,fwrite

Voir version :

Pas de dépendances

Télécharger :

#include <stdio.h>

char* Charger(const char* fic,int* taille)
{
    char* res;
    FILE* F = fopen(fic,"rb");
    *taille = 0;
    if (!F)
        return NULL;
    fseek(F,0,SEEK_END);
    *taille = ftell(F);
    fseek(F,0,SEEK_SET);
    res = malloc(*taille);
    fread(res,*taille,1,F);
    fclose(F);
    return res;
}

int Sauver(const char* fic,char* memoire,int taille)
{
    FILE* F = fopen(fic,"wb");
    if (!F)
        return -1;
    fwrite(memoire,taille,1,F);
    fclose(F);
    return 0;
}

void Liberer(char* mem)
{
    if (mem)
        free(mem);
}

int main()
{
    char* memoire;
    int taille;
    memoire = Charger("01_01_06_chargersauver.c",&taille);
    // memoire est un tableau dynamique, modifie ce que tu veux
    Sauver("copie.c",memoire,taille);
    Liberer(memoire);
    return 0;
}




Commentaires

	Voici comment lire tout un fichier d'un seul coup dans un tableau, et le réécrire, ce qui fera une copie du fichier.
	
	Si vous lancez le programme (avec le fichier 01_01_06_chargersauver.c dans le répertoire de travail, ça va le copier comme "copie.c"
	Mais vous pouvez mettre le fichier que vous voulez (même un EXE, un AVI, ce que vous voulez !)

	La fonction Charger va entièrement copier le fichier dans le tableau "memoire", et remplir aussi la taille du tableau retourné.

	Pour cela, une méthode simple qui, paraît il, pourrait ne pas être parfaitement exacte sur certains vieux systèmes, mais qui ne m'a personnellement jamais posé de soucis :

	On ouvre le fichier en mode "rb" -> très important, on l'ouvre en binaire. (1)

	Le fseek 0 sur SEEK_END permet de placer le curseur du fichier à la fin. Le ftell qui suit nous dit ou est le curseur, donc finalement, quelle est la taille du fichier.
	Ensuite, on alloue la mémoire qu'il faut, on remet le curseur au début avec un fseek 0 sur SEEK_SET, puis avec un seul fread, on lit le fichier en mémoire.

	Un seul fread permet de lire le fichier le plus vite possible. 
	Certains lisent les fichiers octet par octet en appelant taille*fgetc : les performances sont alors effondrées.
	Pour avoir de bons accès aux disques, essayez de lire les plus gros blocs possibles avec un seul fread.

	Sortie de la fonciton Charger, vous pouvez modifier le tableau à votre guise....

	Puis on resauve le fichier en mode binaire "wb" avec un seul fwrite pour des performances optimales.

	Note : je pars du principe que vous avez assez de RAM pour contenir tout le fichier en mémoire.

	----------------------------------------------------

	(1) Ouvrir un fichier en binaire permet de considérer chaque octet de la même manière. Si vous ne l'ouvrez pas en binaire, mais en texte (avec "r") alors il pourra y avoir
	un traitement particulier pour les caractère '\n', qui peut varier d'un OS à l'autre. 
	
	Ainsi, si vous lisez un 0x0D, vous pourrez avoir une lecture implicite d'un 0x0A qui suit, car Certains OS comme Windows ou Mac par exemple codent le '\n' avec 2 octets.
	(tout ceci étant un héritage de vieilles imprimantes....)

	Pareil pour l'écriture, écrire un 0D pourra implicitement être suivi d'un 0A si vous écrivez en mode "w" (texte).
	Ainsi il y aura plus d'octets que voulu à la fin.

	Donc pour lire et écrire du binaire : "rb" et "wb" -> ainsi, pas de traitements particuliers pour un octet spécifique.