Savoir si un fichier est utilisé par une autre application..
cs_Gerard
Messages postés121Date d'inscriptionjeudi 10 janvier 2002StatutMembreDernière intervention 7 août 2018
-
Modifié par cs_Gerard le 10/05/2015 à 12:56
cs_Gerard -
14 mai 2015 à 20:54
Bonjour,
j'ai de temps à autre une erreur sur mon serveur qui veut enregistrer des données en cours, un message qui signale que le fichier ne peut pas être créé car il est occupé par une autre application.
Il n'y a pas d'autre application qui utilise ce fichier, et donc je voudrais savoir s'il y a un moyen de savoir si le fichier est occupé avant de le sauvegarder et provoquer une erreur...
Merci!
NHenry
Messages postés15049Date d'inscriptionvendredi 14 mars 2003StatutModérateurDernière intervention25 mars 2023156 10 mai 2015 à 12:42
Bonjour,
Merci de garder à l'esprit que CodeS-SourceS est une communauté d'entraide. Toutes les réponses sur le forum sont assurées par des bénévoles qui donnent de leur temps libre pour aider à résoudre les problèmes.
A noter qu'il est expressément demandé aux utilisateurs des forums de faire preuve de respect mutuel dans les discussions. Par conséquent, lors de la demande d'assistance, merci d'être courtois et d'utiliser des formules de politesse, "comme dans la vraie vie" dans des circonstances similaires (dire "bonjour", "s'il vous plaît", "merci", etc...)
A noter également que nous ne faisons pas dans le "tout cuit". Soit tu trouves ton bonheur dans la partie source du site, soit à l'aide de ton moteur de recherche favori. Ici, nous aidons volontiers sur des sujets techniques précis.
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 14 mai 2015 à 15:32
Bonjour,
si le système te dit que ton fichier est utilisé par une autre application alors que c'est faux ...
ça veut dire que lors de la dernière utilisation de ton application elle a planté ou que tu ne libères pas correctement le handle du fichier en question avant de quitter l'application et du coup il reste "utilisé par une autre application" pour le système
dans tous les cas c'est un défaut dans le code
NHenry
Messages postés15049Date d'inscriptionvendredi 14 mars 2003StatutModérateurDernière intervention25 mars 2023156 14 mai 2015 à 15:42
Merci de cette réponse, mais il m'est difficile de croire que ce soit un défaut dans le code.
en effet c'est toujours le même code qui est exécute pour dans des threads différents, (un par joueur et il y en a 700, le fichier étant propre au joueur) et cette sauvegarde est appelée plusieurs centaines de milliers de fois par jour, et cela tous les jours.
or l'erreur ne se produit que de temps à autre, une fois par semaine peut-être...
ma question n'était pas d'en connaitre la cause, mais de savoir si on pouvait tester l'état du fichier: il doit bien y avoir un bit quelque part qui déclenche l'erreur, et si on pouvait le tester avant d'écrire cela ne déclencherait pas l'erreur..
Ce qui n'est pas vraiment gênant si de temps à autre le fichier n'est pas sauvegardé: cela est fait pour saisir l'état du jeu du joueur pour pouvoir le reprendre en cas d'interruption là où il a été laissé.
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 14 mai 2015 à 20:08
re,
Comme tu ne donnes pas de code en exemple on ne peut pas être certain que tout soit correctement libéré
et c'est pas parce que le code fonctionne des milliers de fois qu'il ne peut pas planter à la suivante !!!
est ce que tu utilises bien des bloc try/finally partout pour garantir la libération du fichier à tous les coups?
voici un exemple de code qui fait ce que tu demandes ...
en premier lieu j'occupe le fichier (code dans le OnCreate) qui est d'ailleurs un parfait exemple de ce qu'il ne faut pas faire parce qu'en cas de plantage de l'application le fichier restera ouvert (Mais c'est utile pour l'exemple) et ensuite j'essaye de l'ouvrir par l'action du bouton:
var
aFS: TFileStream;
procedure TForm1.FormCreate(Sender: TObject);
begin
aFS := TFileStream.Create('Mon_Fichier.txt', fmOpenReadWrite or fmShareExclusive or fmCreate);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
FS: TFileStream;
begin
try
FS := TFileStream.Create('Mon_Fichier.txt', fmOpenReadWrite or fmShareExclusive or fmCreate);
try
//ici écriture sur le disque
finally
FS.Free;
end;
except
ShowMessage('Fichier déjà ouvert');
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
aFS.Free
end;
si ça ne résout pas ton problème et il y a de grandes chances que ce soit le cas, il faudra que tu nous donnes le code (basic) de sauvegarde et le thread ... il y a 9 chances sur 10 pour que le bug se cache dedans
ps: si le fichier est vraiment considéré déjà ouvert par le système et tu maintiens que c'est faux
le fait de tester ne changera rien ... tu ne pourras quand même pas enregistrer !!!!
il faut absolument libérer le fichier
soit comme le dit NHenry avec un programme externe comme Unlocker
soit en redémarrant le système
soit en corrigeant le code qui provoque cette erreur.
Oui tu as raison... bon le code est simple: le fichier est une TstringList et la sauvegarde est tout bêtement un SaveTofile.
c'est-à-dire pou ce cas-là je ne m'occupe pas d'ouvrir le fichier et de le refermer
(par contre c'est ce que je fais pour le journal qui suit l'action de chaque joueur: je sais donc le faire...)
donc ma question est simple: Est-ce qu'avant de procéder à un SaveToFile on peut tester l'état du fichier qui ne peut être occupé que par la même application..
je dois préciser, qu'il est possible que le joueur soit sollicité par plusieurs connexions (les navigateurs qui s'adressent au serveur peuvent le faire au travers de plusieurs connexions et là je subis), il peut donc y avoir plusieurs threads qui vont faire des SaveTofile (difficile à identifier en temps réel!) mais je n'ai jamais réussi à vérifier que c'était là le problème..
Peut-être faut-il protéger le SaveToFile par une section critique?
mais là si cela se passe mal on plante le joueur...