Question

Je dois développer une application qui analyse un fichier journal et envoie des données spécifiques à un serveur.Il doit fonctionner sous Linux et Windows.

Le problème apparaît lorsque je souhaite tester le système de roulement de journaux (qui ajoute .1 au nom du et en crée un nouveau avec le même nom).Sous Windows (pas encore testé sous 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 saisie" (ios::in) .

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

Était-ce utile?

La solution

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

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

est-ce multiplateforme ?

Non, cela nécessite un code spécifique à la plateforme.

En raison de problèmes de compatibilité ascendante (les applications DOS, étant mono-tâches, supposent que rien ne peut supprimer un fichier sous elles, c'est-à-direqu'ils peuvent fclose() puis fopen() sans que rien ne se passe mal ;Win16 a conservé cette hypothèse pour faciliter le portage des applications DOS, Win32 a conservé cette hypothèse pour faciliter le portage des applications Win16, et c'est horrible), Windows ouvre par défaut les fichiers exclusivement.

L'infrastructure du système d'exploitation sous-jacente prend en charge la suppression/renommage des fichiers ouverts (même si je pense qu'elle a la restriction que les fichiers mappés en mémoire ne peuvent pas être supprimés, ce qui, je pense, n'est pas une restriction trouvée sur * nix), mais la sémantique d'ouverture par défaut ne le fait pas.

C++ n’a aucune idée de tout cela ;l'environnement d'exploitation C++ est sensiblement le même que l'environnement d'exploitation DOS : aucune autre application ne s'exécute simultanément, donc pas besoin de contrôler le partage de fichiers.

Autres conseils

Ce n'est pas l'opération de lecture qui nécessite le mode exclusif, c'est le changement de nom, car cela revient essentiellement à 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 plutôt de copier le fichier, puis supprimez/remplacez l'ancien fichier lorsqu'il n'est plus lu.

La sémantique du système de fichiers Win32 exige qu'un fichier que vous renommez ne soit pas ouvert (dans aucun mode) au moment où vous effectuez le changement de nom.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 vers l'inode.

Si vous lisez uniquement le fichier, je sais que cela peut être fait avec l'API Windows CreateFile.Il suffit de spécifier FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE en tant qu’entrée de dwShareMode.

Malheureusement, ce n'est pas multiplateforme.Mais il pourrait y avoir quelque chose de similaire pour Linux.

Voir msdn pour plus d'informations sur CreateFile.

MODIFIER:Juste un petit mot sur le commentaire de Greg Hewgill.Je viens de tester avec le truc FILE_SHARE* (soyez également 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*.

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

  1. Résumé (lecture/écriture/passage vers un nouveau fichier) dans une classe et organisez la fermeture du fichier lorsque vous souhaitez passer à un nouveau fichier dans cette classe.(c'est le moyen le plus simple, et comme vous avez déjà le code roll-over, vous êtes déjà à mi-chemin.)
  2. Si vous devez disposer de plusieurs points d'accès en lecture/écriture, avez besoin de toutes les fonctionnalités de fstreams et ne souhaitez pas écrire cela dans un wrapper complet, la seule solution multiplateforme à laquelle je puisse penser est de toujours fermer le fichier lorsque vous n'en avez pas besoin. , et demandez au code de roll-over d'essayer d'acquérir un accès exclusif au fichier à plusieurs reprises lorsqu'il doit être roll-over avant d'abandonner.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top