Comment forcer le vidage du fichier

Supposons que j’ai le code suivant:

#include  #include  #include  int main() { std::ofstream f("test.log"); int i = 0; while (true) { f << i++; f.flush(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } 

(notez que j’ai un appel de flush après chaque opération d’écriture)

J’ai remarqué que cette application ne met pas à jour les atsortingbuts de “dernière modification” et de “taille” du fichier “test.log” à moins que je ne fasse un clic droit sur ce fichier ou que je ne l’ouvre.

J’imagine que cela est dû à une mise en mémoire tampon interne (le système ne veut pas effectuer des opérations aussi longues qu’une E / S sur disque, à moins d’y être contraint). Ai-je raison?

Je dois écrire une application qui doit surveiller les modifications apscopes aux fichiers journaux créés par d’autres applications (je ne peux pas les modifier). Au début, je pensais à la classe FileSystemWatcher en C #, mais j’ai remarqué qu’elle avait le même comportement (il ne déclenche pas l’événement correspondant à moins que le fichier soit fermé dans une application source ou forcé de se mettre à jour en cliquant avec le bouton droit de la souris dans l’explorateur Windows. ). Que puis-je faire alors? Appelez WinAPI comme GetFileAtsortingbutes pour chaque fichier que je souhaite rechercher aussi souvent que possible.

Il y a deux choses distinctes ici. Tout d’abord, la dernière fois modifiée sur le fichier enregistrement MFT (équivalent inode) est mise à jour chaque fois que vous écrivez dessus.

Toutefois, les informations renvoyées par FindFirstFile et ses amis ne proviennent pas du fichier, mais des informations mises en cache dans l’entrée de répertoire. Ce cache est mis à jour chaque fois qu’un fichier est fermé et a été ouvert via cette entrée de répertoire . Il s’agit des informations affichées par la plupart des applications, telles que l’explorateur Windows et la commande DIR d’invite de commande.

Si vous voulez savoir quand un fichier a été mis à jour, vous devez effectuer l’équivalent d’une opération stat Unix qui lit l’enregistrement MFT (inode). Cela nécessite d’ouvrir un GetFileInformationByHandle sur le fichier, d’appeler GetFileInformationByHandle et de refermer le GetFileInformationByHandle .

Deuxièmement, il y a une bonne raison de ne pas le faire. Si un programme écrit dans un fichier, il se peut que le processus d’écriture soit en cours. Par conséquent, le fichier peut être dans un état non valide (corrompu). Pour vous assurer que le fichier est dans un état valide, vous devez attendre sa fermeture. Voici comment vous savez que le fichier est maintenant prêt à être consulté.

Une fois que le programme d’écriture a fini d’écrire dans le fichier, l’entrée du répertoire est mise à jour et FileSystemWatcher affiche le fichier.

Si vous êtes absolument certain de vouloir voir les notifications de fichiers en cours d’écriture, vous pouvez consulter le journal des modifications USN en tant qu’option. Je ne sais pas si cela est plus à jour que les entrées du répertoire, vous devrez vous renseigner.