2010-09-15 38 views
3

Disons que plusieurs fonctions de mon programme doivent ajouter des données à un certain fichier. J'ouvre le fichier au début du programme avec un handle de fichier global afin que je puisse y ajouter où je le souhaite. (Notez que je sais que je pourrais passer le handle de fichier comme argument aux fonctions mais ce n'est pas le but de cette question). Est-ce mauvais d'ouvrir le handle de fichier au début d'un programme, puis fermez-le à la fin; ou est-il préférable d'avoir une fonction dites void AppendFile(char *data_to_append); puis ouvrez le fichier et ajoutez-y et fermez-le dans cette même fonction? Si le programme meurt, le FD sera toujours utilisé est la seule mauvaise chose que je vois, mais en même temps vous ouvrez et fermez le même fichier des centaines et des centaines de fois si vous utilisez la fonction.L'ajout à un descripteur de fichier global est-il mauvais?

+0

Avez-vous entendu parler de 'stdout'? C'est un gestionnaire de fichiers global qui est créé au démarrage (avant) et est disponible pour utilisation. –

+0

Oui, je l'ai, et il est déjà utilisé pour autre chose. – user318747

Répondre

2

Il est probablement préférable de faire une seule ouverture et une seule fermeture. L'ouverture/fermeture sans arrêt conduira à beaucoup d'E/S perdues.

Vous voudrez probablement protéger cette fonction avec un mutex afin qu'un seul thread puisse écrire sur la poignée de fichier à la fois.

Assurez-vous que vous fermez votre fichier si finalement.

0

Oui.

Pas la réponse la plus utile mais je crains que votre question soit trop générale et vague pour vous donner quelque chose de détaillé. Si vous avez accès à cette FD dispersée dans votre programme, cela suggère qu'il y a un problème avec votre design de haut niveau. Ces accès distincts sont-ils liés les uns aux autres d'une manière ou d'une autre? Pourraient-ils être combinés en un plus petit nombre de points qui accèdent au fichier? Avez-vous une sorte de structure de données implicite dans votre programme qui serait mieux implémentée dans une classe?

+0

Whoah, les cours? L'étiquette indique C. – nmichaels

+0

N'a pas remarqué que ce n'était pas là quand j'ai répondu. Je laisserai le commentaire dedans comme tout le monde sait que C ne vous empêche pas de faire OO si vous êtes assez déterminé et manque de limites normales de santé mentale ... – Amoss

1

Si votre programme est mono-thread, c'est bon. Si elle meurt alors que la poignée du fichier est ouverte, elle peut être fermée par le système d'exploitation de toute façon. Si ce n'est pas le cas, qu'est-ce qui garantit qu'il ne mourra pas dans votre fonction AppendFile?

Je vous suggère de faire cette fonction AppendFile si. Cela simplifiera le processus d'écriture et vous serez en mesure de changer les choses à propos du gestionnaire de fichiers plus facilement qu'avec un tas de fwrite() saupoudré.

1

Dépend de combien vous vous souciez de votre fichier ne pas être saccagé ou perdre des données. Si le programme se bloque, il n'y a aucune garantie quant à ce qui arrive à toutes les écritures qui n'ont pas été terminées (pas seulement terminées, mais vidées et validées sur le disque). S'il y a des écritures non validées, elles peuvent être jetées ou à moitié faites. La fermeture du fichier garantit que ces écritures sont validées. Si les écritures sont peu fréquentes, open/append/close est une meilleure idée IMO - mais AppendFile peut être configuré pour fonctionner avec une poignée de fichier déjà ouverte, donc cela fonctionne mieux dans les deux cas.

Ajoutez à cela, si vous utilisez des threads du tout, vous ne voulez pas d'écritures aléatoires dans le fichier - vous voulez avoir un moyen de les synchroniser. Avoir une AppendFile ou une fonction similaire vous donne ce point de synchronisation - vous pouvez ajouter du code là-bas pour attendre qu'un autre thread soit terminé. Essayez de le faire lorsque vous écrivez directement dans le fichier dans une centaine d'endroits différents.

+0

append/flush/append/flush donnera une aussi bonne garantie que les choses sont écrites. – nmichaels

+0

Si quelqu'un se souvient de tirer la chasse d'eau. Ce qu'ils pourraient très bien ne pas. Un autre argument en faveur de 'AppendFile'. :) – cHao

1

Parfois, une base de données est un très bon substitut pour les fichiers texte, expecially lorsque la base de données a été spécialement conçu pour remplacer les fichiers texte en premier lieu :)

Jetez un oeil à SQLite (http://www.sqlite.org/).

Pensez SQLite pas en remplacement d'Oracle, mais en remplacement de fopen()

0

Si par descripteur de fichier que vous voulez dire un FILE * puis en ouvrant au début et à la fermeture à la fin avec beaucoup de les utilisateurs devraient fonctionner comme prévu même s'il y a plusieurs threads tant que vous faites vos écritures avec des appels de fonction stdio simples sur les systèmes POSIX. Si par handle de fichier vous voulez dire un entier renvoyé par l'appel ouvert du système d'exploitation, ils sont généralement thread safe dans un seul appel à write (ou similaire) puisque le système d'exploitation verrouillera le fichier tout en transférant des données aux tampons associés à ce fichier.

Si le programme est une application à un seul thread, vous n'avez pas grand-chose à craindre.

Si vous deviez aller avec l'ouverture à plusieurs reprises, annexant, et fermer le fichier que vous pourriez avoir des ennuis si vous utilisez FILE * de stdio avec plusieurs threads ou si les appels à AppendFile étaient en quelque sorte fait récursive parce que les différents FILE * s ne partagerait pas les tampons dans l'application et de sorte que le fichier a changé dans un thread d'autres threads pourraient remplacer ces changements. Une chose similaire peut se produire avec les poignées de fichiers OS (entiers retournés par open) puisque les différents appels à open produiront des handles de fichiers différents avec ne pas partager leur position de recherche, donc que le fichier a grandi les différents descripteurs de fichiers finiraient avec des positions de recherche qui n'étaient pas réellement à la fin du fichier sauf si vous pouvez ouvrir le fichier en mode ajout seul (O_APPEND) où le système d'exploitation gère cela pour vous.

L'ouverture et la fermeture répétées du fichier génèrent beaucoup de travail supplémentaire, dans les deux cas.

1

Les variables globales ne sont généralement pas une bonne chose. Pour les petits programmes, ce n'est pas grave cependant. Tout en utilisant toujours un descripteur de fichier global, envisagez d'y accéder uniquement via une fonction void AppendFile(char *data_to_append);, où seul le AppendFile fait référence au fichier global, au lieu de le disperser partout dans votre code.

L'ouverture/fermeture d'un fichier à chaque accès peut être un problème si le fichier est souvent consulté.

En outre, les handles de fichiers sont normalement fermés lorsque votre programme se termine (soit meurt, soit se ferme normalement), donc vous ne ferez rien si votre programme plante.