2008-08-26 10 views
4

Je dois développer une application qui analyse un fichier journal et envoie des données spécifiques à un serveur. Il doit fonctionner à la fois sur Linux et Windows.C++: Ouverture d'un fichier en mode non exclusif

Le problème apparaît quand je veux tester le système de roulement de journal (qui ajoute au nom .1 de crée un nouveau avec le même nom). Sous Windows (je n'ai pas encore testé sur Linux) je ne peux pas renommer un fichier que j'ai ouvert avec std :: ifstream() (accès exclusif?) Même si je l'ouvre en "mode entrée" (ios :: in) .

Existe-t-il un moyen multi-plateforme d'ouvrir le fichier de manière non-exclusive?

Répondre

3

Est-il possible d'ouvrir le fichier d'une manière non exclusive,

Oui, en utilisant Win32, en passant les différents drapeaux de FILE_SHARE_Xxxx à CreateFile.

est-il multi-plateforme?

Non, il nécessite un code spécifique à la plate-forme. En raison de problèmes de compatibilité descendante (les applications DOS, étant une seule tâche, supposons que rien ne peut effacer un fichier de dessous, c'est-à-dire qu'elles peuvent fclose() et fopen() sans que rien ne se passe; cette hypothèse pour faciliter le portage des applications DOS, Win32 a préservé cette hypothèse pour faciliter le portage des applications Win16, et c'est horrible), Windows par défaut ouvre les fichiers exclusivement. L'infrastructure du système d'exploitation sous-jacent supporte la suppression/le renommage des fichiers ouverts (bien que je pense qu'il est impossible de supprimer les fichiers mappés en mémoire, ce qui n'est pas une restriction trouvée sur * nix), mais l'ouverture par défaut la sémantique ne le fait pas.

C++ n'a aucune notion de cela; l'environnement d'exploitation C++ est sensiblement le même que l'environnement d'exploitation DOS - aucune autre application n'est exécutée simultanément, donc pas besoin de contrôler le partage de fichiers.

1

Ce n'est pas l'opération de lecture qui est exigeant le mode exclusif, il est le changement de nom, parce que c'est essentiellement le même que déplacer le fichier vers un nouvel emplacement.

Je ne suis pas sûr mais je ne pense pas que cela puisse être fait. Essayez de copier le fichier à la place et, plus tard, supprimez/remplacez l'ancien fichier lorsqu'il n'est plus lu.

1

La sémantique du système de fichiers Win32 nécessite qu'un fichier renommé ne soit pas ouvert (quel que soit le mode) au moment du renommage. Vous devrez fermer le fichier, le renommer, puis créer le nouveau fichier journal.

La sémantique du système de fichiers Unix vous permet de renommer un fichier ouvert car le nom de fichier n'est qu'un pointeur sur l'inode.

1

Si vous lisez seulement à partir du fichier, je sais que cela peut être fait avec windows api CreateFile. Spécifiez simplement FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE en tant qu'entrée de dwShareMode.

Malheureusement, ce n'est pas une plateforme croisée. Mais il pourrait y avoir quelque chose de similaire pour Linux.

See msdn for more info on CreateFile.

EDIT: Juste une note rapide au sujet du commentaire de Greg Hewgill. Je viens de tester avec le contenu de FILE_SHARE * (soyez aussi sûr à 100%). Et il est possible à la fois de supprimer et de renommer des fichiers dans Windows si vous ouvrez en lecture seule et spécifiez les paramètres FILE_SHARE *.

0

Je m'assurerais que vous ne gardez pas les fichiers ouverts. Cela conduit à des choses étranges si votre application se bloque par exemple. Ce que je ferais:

  1. Résumé (lecture/écriture/rouler sur un nouveau fichier) dans une classe, et d'organiser la fermeture du fichier lorsque vous souhaitez rouler sur un nouveau dans cette classe. (C'est la façon la plus simple, et puisque vous avez déjà le code de retour, vous êtes déjà à mi-chemin.)
  2. Si vous devez avoir plusieurs points d'accès en lecture/écriture, vous avez besoin de toutes les fonctions des fstreams et vous ne voulez pas écrire que remplir un wrapper puis la seule solution multi-plateforme que je peux penser est de toujours fermer le fichier lorsque vous n'en avez pas besoin, et le code de roll-over essayer d'acquérir un accès exclusif au fichier à plusieurs reprises quand il a besoin rouler avant d'abandonner.
Questions connexes