116 votes

Quelle est la raison pour laquelle fread / fwrite prend la taille et compte comme arguments?

Nous avons eu une discussion ici au travail de la raison pour laquelle fread et fwrite prendre une taille par membre et de les compter et de retourner le nombre de membres en lecture/écrite, plutôt que de simplement prendre un tampon et de la taille. La seule utilisation que pour ça, on pourrait arriver, c'est si vous voulez lire/écrire un tableau de structures qui ne sont pas divisibles par la plate-forme de l'alignement et ont donc été rembourré, mais qui ne peut pas être si commun pour justifier ce choix dans la conception.

De FREAD(3):

La fonction fread() lit nmemb éléments de données, chacun de la taille octets de long, à partir du flux pointé par stream, de les stocker à l'emplacement donné par ptr.

La fonction fwrite() écrit nmemb éléments de données, chacun de la taille octets longtemps, les flux pointé par stream, l'obtention de l'endroit donné par ptr.

fread() et fwrite() retourne le nombre d'éléments correctement lu ou écrit (c'est à dire, pas le nombre de caractères). Si une erreur se produit, ou l' en fin de fichier est atteinte, la valeur de retour est une courte distance de l'élément de comptage (ou zéro).

88voto

Peter Miehle Points 3753

La différence entre fread (buf, 1000, 1, stream) et fread (buf, 1, 1000, stream) est que, dans le premier cas, vous n’obtenez qu’un bloc de 1000 octets ou nuthin, si le fichier est plus petit et dans le Dans le second cas, le fichier contient moins de 1000 octets.

26voto

Powerlord Points 43989

Il est basé sur la façon dont fread est mis en œuvre.

La Single UNIX Specification dit

Pour chaque objet, de la taille appels doivent être fait à la fgetc() et la fonction de la les résultats stockés, dans l'ordre de lecture, en un tableau de unsigned char exactement la superposition de l'objet.

fgetc a aussi cette remarque:

Depuis fgetc() fonctionne sur des octets, la lecture d'un caractère composé de plusieurs octets (ou "multi-octets caractère") peut nécessiter plusieurs appels de fgetc().

Bien sûr, cela précède fantaisie variable d'octets codages de caractères comme de l'UTF-8.

SUS note que c'est en fait tiré de l'ISO C documents.

19voto

nos Points 102226

C’est une pure spéculation, mais à l’époque (certains sont toujours là), de nombreux systèmes de fichiers ne sont pas de simples flux d’octets sur un disque dur.

De nombreux systèmes de fichiers étaient basés sur des enregistrements. Ainsi, pour satisfaire ces systèmes de fichiers de manière efficace, vous devez spécifier le nombre d'éléments ("records"), ce qui permet à fwrite / fread de fonctionner sur le stockage en tant qu'enregistrements, et pas uniquement en flux d'octets.

10voto

Michael Burr Points 181287

Ici, permettez-moi de corriger ces fonctions:

size_t fread_buf( void* ptr, size_t size, FILE* stream)
{
    return fread( ptr, 1, size, stream);
}


size_t fwrite_buf( void const* ptr, size_t size, FILE* stream)
{
    return fwrite( ptr, 1, size, stream);
}

Comme pour une justification pour les paramètres d' fread()/fwrite(), j'ai perdu ma copie de K&R il y a longtemps donc je ne peut que deviner. Je pense qu'une réponse probable est que Kernighan et Ritchie peut tout simplement avoir pensé que l'exécution de binaires I/O serait le plus naturellement fait sur les tableaux d'objets. Aussi, ils ont peut-être pensé que le bloc d'e/S serait plus rapide/plus facile à mettre en œuvre ou de quoi que ce soit sur certaines architectures.

Même si la norme spécifie que fread() et fwrite() être mis en œuvre en termes de " fgetc() and fputc()`, n'oubliez pas que la norme est venu à l'existence, longtemps après C a été définie par K&R et que les choses spécifiées dans la norme pourrait ne pas avoir été à l'origine, les concepteurs d'idées. Il est même possible que ce qui est dit dans le K&R "Le Langage de Programmation C" est peut-être pas la même que lorsque la langue a d'abord été conçu.

Enfin, voici ce que P. J. Plauger a à dire à propos de fread() dans "La Bibliothèque Standard C":

Si l' size (deuxième argument) est supérieur à un, vous ne pouvez pas déterminer si la fonction de lecture jusqu'à size - 1 caractères supplémentaires au-delà de ce qu'il indique. En règle générale, vous êtes mieux de l'appel de la fonction en tant que fread(buf, 1, size * n, stream); au lieu de fread(buf, size, n, stream);

Bascially, il dit qu' fread()'interface est cassé. Pour fwrite() il note que, "les erreurs d'Écriture sont généralement rares, donc ce n'est pas une lacune majeure" - une déclaration que je ne serais pas d'accord avec.

3voto

dolch Points 294

Cela revient probablement à la façon dont cette E / S de fichier a été implémentée. (retour dans la journée) Il aurait peut-être été plus rapide d'écrire / lire dans des fichiers en blocs que de tout écrire en une fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X