9Fermer11
ZerosquareLe 07/12/2014 à 00:52
Faire ça octet par octet, ça veut dire 3 appels de fonction par octet copié. Certes il y a un cache, mais ça va quand même ramer et bouffer 100% du CPU pour rien du tout ; c'est une méthode indigne d'un codeur qui se respecte embarrassed
Utiliser un buffer dont la taille est une puissance de 2 (pour que ça corresponde à un nombre entier de secteurs) est bien meilleur.

Sinon, effectivement, ton code va échouer si la taille du fichier n'est pas un multiple entier de la taille du buffer, ou si elle est nulle. Le patch de Pen² corrige ce bug, mais en introduit un autre plus subtil : le fait que fread() renvoie une valeur plus petite que la taille du buffer ne veut pas forcément dire que tu as atteint la fin du fichier "normalement", ça peut être aussi que la lecture a échoué. Dans ce cas, ton code va soit partir en boucle infinie, soit se terminer normalement sans prévenir qu'il y a eu une erreur, suivant la valeur renvoyée par feof(). Il faut donc rajouter un appel à ferror() après fread() pour faire la différence entre la fin du fichier et une erreur de lecture.

Note qu'il y a des arguments pour laisser faire l'OS plutôt que réinventer la roue pour copier les fichiers :
- ça fait du code en moins à taper
- ça évite d'introduire des bugs cheeky
- ça supporte les fichiers de 232 octets et plus, ce qui n'est pas le cas de toutes les versions de la libc
- ça copie efficacement et correctement les fichiers spéciaux (symlinks, fichiers avec 2 streams ou plus, fichiers "creux"...)
- ça copie aussi les attributs (date de création originale, droits d'accès...)
- suivant l'OS, ça peut permettre d'éviter la recopie de buffers -> plus rapide
- suivant l'OS, ça peut permettre la copie de manière asynchrone, ce qui permet à l'utilisateur d'interrompre l'opération (par exemple si la source est un lecteur réseau inaccessible avec un timeout long) sans devoir se farcir du multithreading

EDIT : cross