J'ai un seul programme fileté (C ++, Win32, NTFS) qui crée d'abord un fichier temporaire assez long, la ferme, s'ouvre pour lire, se lit, ferme à nouveau et essaie de supprimer à l'aide de Il va généralement bien, mais parfois Des idées Qu'est-ce qui peut verrouiller le fichier? J'ai essayé Wininternals Tools de vérifier et n'a rien trouvé de suspect. P> deletefile () code >. P>
deletefile ( code>) échoue, et
getlasterror () code> renvoie error_access_denied. Le fichier n'est pas en lecture seule à coup sûr. Cela se produit sur des fichiers de n'importe quelle taille, mais la probabilité se développe avec la taille du fichier. P>
7 Réponses :
Peut-être que les changements sont toujours mis en cache et n'ont pas encore été sauvés? P>
Vous pouvez vérifier cela en ajoutant un waitforsingleObject em> sur la poignée de fichier pour être sûr. p>
L'écriture de la mise en cache est transparente à l'application. Cela ne devrait pas causer de changement de comportement.
Ajouter une MessageBox () Appelez avant d'invoquer DeleteFile (), lorsqu'il apparaît, exécutez l'explorateur de processus Tool Sysinternals. Rechercher une poignée ouverte dans le fichier. Dans toutes les probabilités, vous n'avez pas fermé toutes les poignées au fichier ... p>
C'est ce que j'avais commencé à partir de. Pas de poignées. Alors j'ai ensuite enregistré tous les accès au fichier et rien de spécial.
Cela ressemble à une condition de course (éventuellement sur l'ordre des millisecondes), donc à moins que vous ne gèlez pas tout, vous ne pourrez peut-être pas reproduire le bug de cette façon. (Mais essayant certainement d'aider à réduire les possibilités.)
Juste une supposition sauvage - Avez-vous un logiciel anti-virus installé? Avez-vous essayé de désactiver toutes les fonctionnalités de protection en temps réel, si vous le faites? P>
Windows est notoire pour ce problème. SQLite gère le problème en réessayant l'opération de suppression toutes les 100 millisecondes jusqu'à un nombre maximal.
Je crois que si vous êtes sûr que vous n'avez pas de poignées ouvertes, cela vous permettra de faire des maux de tête lorsque des choses comme des logiciels antivirus ouvrent le fichier. p>
pour référence, le commentaire de SQLite Source : p>
Je crois que ceci est couvert dans Windows Internals . La courte histoire est que même si vous avez appelé CERTERHANDLEL sur la poignée de fichier, le noyau peut toujours avoir des références exceptionnelles qui prennent quelques millisecondes à fermer.
Un moyen plus fiable de supprimer le fichier lorsque vous avez terminé est de supprimer le fichier lorsque vous avez terminé. Utilisez le drapeau File_Flag_Delete_on_FLOSE lors de l'ouverture de la dernière poignée. Cela fonctionne encore mieux si vous pouvez éviter de fermer le fichier entre des lectures / écrit. P>
Cela ne va pas échouer si un autre processus a ouvert le même fichier, compte tenu de la description suivante de la documentation? "S'il existe des poignées ouvertes existantes dans un fichier, l'appel échoue à moins qu'ils n'étaient pas ouverts avec le mode de partage File_Share_Delete."
Oui, c'est pourquoi j'ai recommandé de ne pas fermer la poignée du fichier entre les écritures et les lis. Créez la première poignée avec fichier_flag_delete_on_close, puis utilisez la répétition ou la dupliquée. Si vous avez vraiment besoin d'une poignée de fichier qui n'a pas d'accès en écriture.
Peut-être que je suis lent aujourd'hui, mais ce n'est-il pas toujours un problème si quelqu'un Sneaky ouvre le fichier avant le dernier appel à Createfile? Le dernier appel va toujours échouer.
Vous voulez utiliser FILE_FLAG_DELETE_ON_CLOSE sur un appel Single i> à Createefile, il n'y a aucune chance de fuir le fichier. Sinon, tous les paris sont éteints. Si vous avez besoin d'une poignée de fichier avec différents drapeaux ou droits, vous devez utiliser la réouverfile.
Je t'ai eu. Ce n'est pas la question de savoir quelle est la question, mais il y a un bon argument pour structurer le code de cette façon, cela semblerait.
#include <iostream> #include <windows.h> int main(int argc, const char * argv[]) { // Get a pointer to the file name/path const char * pFileToDelete = "h:\\myfile.txt"; bool RemoveDirectory("h:\\myfile.txt"); // try deleting it using DeleteFile if(DeleteFile(pFileToDelete )) { // succeeded std::cout << "Deleted file" << std::endl; } else { // failed std::cout << "Failed to delete the file" << std::endl; } std::cin.get(); return 0; }
Vous pouvez avoir une condition de course. 1. Le système d'exploitation est invité à écrire des données. 2. Le système d'exploitation est demandé de fermer le fichier. Ceci invite le fluillage tampon final. Le fichier ne sera pas fermé jusqu'à ce que le rinçage tampon ne soit effectué. Pendant ce temps, le système d'exploitation retournera le contrôle au programme tout en travaillant sur le rinçage tampon. 3. Le système d'exploitation est invité à supprimer le fichier. Si le rinçage n'est pas encore fait, le fichier sera toujours ouvert et la demande rejetée. P>
Êtes-vous sûr de fermer le fichier correctement avant d'essayer de le supprimer? Avez-vous manqué des poignées?
Comme je l'ai dit, j'ai même vérifié qu'avec Wininternals Tools. Tous les ouvriers sont jumelés avec fermeture, mais la suppression échoue. Et ajouter au sommeil pendant 1 s corrige le problème.
Ce pourrait être des fenêtres d'être buggy mais je suis un peu douteux à ce sujet. Si vous ajoutez le
dormir code> le faire fonctionner doit être bien ^^
En règle générale, si vous ajoutez un appel de sommeil () quelque part fait un problème disparaître, vous devez vous débarrasser de l'appel de sommeil () et résoudre le problème correctement. Ce sera de retour. Je n'ai jamais vu des exceptions à cette règle.
Cela ne fournit pas de réponse à la question. Critiquer ou demander des éclaircissements d'un auteur, laissez un commentaire sous leur poste.