Y a-t-il une raison (autre que syntaxique) que vous voudriez utiliser
FILE *fdopen(int fd, const char *mode);
ou
FILE *fopen(const char *path, const char *mode);
au lieu de
int open(const char *pathname, int flags, mode_t mode);
lors de l'utilisation de C dans un environnement Linux?
fdopen
etopen
oufopen
etopen
?fopen
fait partie de la bibliothèque C standard,open
n'est pas. À utiliserfopen
lors de l'écriture de code portable.open
est une fonction POSIX.Réponses:
Premièrement, il n'y a pas de raison particulièrement valable d'utiliser
fdopen
sifopen
c'est une option etopen
c'est l'autre choix possible. Vous ne devriez pas avoir utiliséopen
pour ouvrir le fichier en premier lieu si vous voulez un fichierFILE *
. Donc, l'inclusionfdopen
dans cette liste est incorrecte et déroutante car elle ne ressemble pas beaucoup aux autres. Je vais maintenant passer à l'ignorer car la distinction importante ici est entre une norme CFILE *
et un descripteur de fichier spécifique au système d'exploitation.Il y a quatre raisons principales d'utiliser
fopen
au lieu deopen
.fopen
vous offre un IO de mise en mémoire tampon qui peut s'avérer beaucoup plus rapide que ce que vous faites avecopen
.fopen
effectue la traduction de fin de ligne si le fichier n'est pas ouvert en mode binaire, ce qui peut être très utile si votre programme est jamais porté vers un environnement non Unix (bien que le monde semble converger sur LF uniquement (sauf la mise en réseau textuelle IETF) protocoles tels que SMTP et HTTP et autres)).FILE *
vous donne la possibilité d'utiliserfscanf
et d'autres fonctions stdio.open
fonction.À mon avis, la fin de la ligne de traduction gêne plus souvent votre chemin que vous aide, et l'analyse de
fscanf
est si faible que vous finissez inévitablement par la jeter en faveur de quelque chose de plus utile.Et la plupart des plates-formes qui prennent en charge C ont une
open
fonction.Cela laisse la question tampon. Dans les endroits où vous lisez ou écrivez principalement un fichier de manière séquentielle, la prise en charge de la mise en mémoire tampon est vraiment utile et améliore considérablement la vitesse. Mais cela peut entraîner des problèmes intéressants dans lesquels les données ne se retrouvent pas dans le fichier lorsque vous vous attendez à ce qu'elles soient là. Vous devez vous souvenir de
fclose
oufflush
aux moments appropriés.Si vous faites des recherches (alias
fsetpos
ou dontfseek
la seconde est légèrement plus délicate à utiliser de manière conforme aux normes), l'utilité de la mise en mémoire tampon diminue rapidement.Bien sûr, mon parti pris est que j'ai tendance à beaucoup travailler avec des sockets, et il y a le fait que vous voulez vraiment faire des E / S non bloquantes (qui
FILE *
ne supportent pas du tout de manière raisonnable) sans tampon du tout et souvent ont des exigences d'analyse complexes colorent vraiment mes perceptions.la source
fgets
,fgetc
,fscanf
,fread
), lira toujours la taille entière du tampon (4K, 8K ou tout ce que vous définissez). En utilisant les E / S directes, vous pouvez éviter cela. Dans ce cas, il est encore préférable d'utiliserpread
au lieu d'une paire de recherche / lecture (1 syscall au lieu de 2).read()
etwrite()
est une cinquième raison pratique d'utiliser la famille de fonctions libc.ioctl
charge prennent également en charge l'fileno
appel qui prend unFILE *
et renvoie un numéro qui peut être utilisé dans unioctl
appel. Soyez prudent cependant.FILE *
les appels associés peuvent interagir de manière surprenante avec l'utilisation deioctl
pour modifier quelque chose au sujet du descripteur de fichier sous-jacent.open()
est un appel os de bas niveau.fdopen()
convertit un descripteur de fichier de niveau os en abstraction FILE de niveau supérieur du langage C.fopen()
appelleopen()
en arrière-plan et vous donne directement un pointeur FILE.Il y a plusieurs avantages à utiliser des objets FILE plutôt que des descripteurs de fichiers bruts, ce qui inclut une plus grande facilité d'utilisation mais également d'autres avantages techniques tels que la mise en mémoire tampon intégrée. En particulier, la mise en mémoire tampon se traduit généralement par un avantage de performance appréciable.
la source
fopen()
ne fournit pas le même niveau de contrôle lors de l'ouverture de fichiers, par exemple créer des autorisations, des modes de partage, etc. généralementopen()
et les variantes offrent beaucoup plus de contrôle, proche de ce que le système d'exploitation fournit réellementmmap
enregistrez le fichier et effectuez des modifications avec des E / S normales (aussi incroyable que cela puisse paraître, nous le faisons en fait dans notre projet et pour de bonnes raisons), la mise en mémoire tampon serait un obstacle.fopen vs open en C
1)
fopen
est une fonction de bibliothèque alors qu'ilopen
s'agit d'un appel système .2)
fopen
fournit des entrées-sorties tamponnées qui sont plus rapides que cellesopen
qui ne le sont pas .3)
fopen
est portable sansopen
être portable ( ouvert est spécifique à l'environnement ).4)
fopen
renvoie un pointeur sur une structure FILE (FILE *) ;open
renvoie un entier qui identifie le fichier.5) A
FILE *
vous donne la possibilité d'utiliser fscanf et d'autres fonctions stdio.la source
open
est un standard POSIX, donc il est assez portableSauf si vous faites partie du 0,1% des applications où l'utilisation
open
est un réel avantage en termes de performances, il n'y a vraiment aucune bonne raison de ne pas l'utiliserfopen
. En ce quifdopen
concerne, si vous ne jouez pas avec des descripteurs de fichiers, vous n'avez pas besoin de cet appel.Bâton avec
fopen
et sa famille de méthodes (fwrite
,fread
,fprintf
, et al) et vous serez très satisfaits. Tout aussi important, d'autres programmeurs seront satisfaits de votre code.la source
Si vous en avez un
FILE *
, vous pouvez utiliser des fonctions commefscanf
,fprintf
etfgets
etc. Si vous avez juste le descripteur de fichier, vous avez des routines d'entrée et de sortie limitées (mais probablement plus rapides)read
,write
etc.la source
Utiliser open, read, write signifie que vous devez vous soucier des interaptions de signaux.
Si l'appel a été interrompu par un gestionnaire de signal, les fonctions renvoient -1 et définissent errno sur EINTR.
Donc, la bonne façon de fermer un fichier serait
la source
close
, cela dépend du système d'exploitation. Il est incorrect de faire la boucle sur Linux, AIX et certains autres systèmes d'exploitation.open()
est un appel système et spécifique aux systèmes basés sur Unix et il renvoie un descripteur de fichier. Vous pouvez écrire dans un descripteur de fichier à l'aide d'write()
un autre appel système.fopen()
est un appel de fonction ANSI C qui renvoie un pointeur de fichier et il est portable sur d'autres systèmes d'exploitation. Nous pouvons écrire dans un pointeur de fichier en utilisantfprintf
.Sous Unix:
vous pouvez obtenir un pointeur de fichier à partir du descripteur de fichier en utilisant:
Vous pouvez obtenir un descripteur de fichier à partir du pointeur de fichier en utilisant:
la source
open () sera appelé à la fin de chacune des fonctions de la famille fopen () . open () est un appel système et fopen () sont fournis par les bibliothèques comme des fonctions d'encapsulation pour un utilisateur facile à utiliser
la source
J'ai changé pour ouvrir () de fopen () pour mon application, car fopen provoquait des doubles lectures à chaque fois que j'exécutais fopen fgetc. Les doubles lectures perturbaient ce que j'essayais d'accomplir. open () semble faire ce que vous lui demandez.
la source
Cela dépend également des drapeaux qui doivent être ouverts. En ce qui concerne l'utilisation pour l'écriture et la lecture (et la portabilité), f * devrait être utilisé, comme expliqué ci-dessus.
Mais si vous voulez spécifier plus que des indicateurs standard (comme les indicateurs rw et append), vous devrez utiliser une API spécifique à la plate-forme (comme POSIX open) ou une bibliothèque qui résume ces détails. La norme C n'a pas de tels indicateurs.
Par exemple, vous souhaiterez peut-être ouvrir un fichier, uniquement s'il se ferme. Si vous ne spécifiez pas l'indicateur de création, le fichier doit exister. Si vous ajoutez exclusif à créer, il ne créera le fichier que s'il n'existe pas. Il y en a bien d'autres.
Par exemple, sur les systèmes Linux, il existe une interface LED exposée via sysfs. Il expose la luminosité de la led à travers un fichier. Écrire ou lire un nombre sous forme de chaîne allant de 0 à 255. Bien sûr, vous ne voulez pas créer ce fichier et n'y écrire que s'il existe. La chose cool maintenant: utilisez fdopen pour lire / écrire ce fichier en utilisant les appels standard.
la source
ouvrir un fichier en utilisant fopen
avant de pouvoir lire (ou écrire) des informations depuis (vers) un fichier sur un disque, nous devons ouvrir le fichier. pour ouvrir le fichier, nous avons appelé la fonction fopen.
ce mode de comportement de la fonction fopen
il y a des causes pendant le processus de mise en mémoire tampon, il peut expirer. Ainsi, tout en comparant l' appel système fopen ( E / S de haut niveau) à l' ouverture (E / S de bas niveau), il est plus rapide et plus approprié que fopen .
la source