Tester si un fichier est déjà ouvert

Résolu
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   -  
trauqnej Messages postés 154 Date d'inscription   Statut Membre Dernière intervention   -

Bonjour,

J'ai un code qui ouvre et qui met à jour un fichier de données (un simple fichier .txt)

Ce code peut être exécuté par plusieurs utilisateurs

Dans le cas où 2 utilisateurs exécuteraient le code au même moment, je veux sécuriser l'opération en ne

permettant l'ouverture du fichier que s'il n'est pas déjà ouvert par un autre

Dans le temps, en C et avec l'api Win32, j'avais fait une boucle d'attente sur une instruction vide tant que le fichier est ouvert:

#include <windows.h>

/* File is in use : waiting... */
while((fh=CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE)
	;
/* File is free */
CloseHandle(fh);

Je me demande si l'on pourrait faire la même chose en Python ?


Windows / Edge 103.0.1264.49

A voir également:

5 réponses

NHenry Messages postés 15219 Date d'inscription   Statut Modérateur Dernière intervention   365
 

Une technique pourrait être de créer un verrou.

Avant d'écrire, tu créé un fichier "Nomfichier.lock", si le fichier existe déjà, tu attends sa disparition, sinon tu créé le fichier, fais ton réécriture, puis le retire.

Si tu a vraiment besoin de multi utilisateur (souvent le signe d'une base de données partagée), il y a des système déjà prévu pour ça (MySql, Postgres, ...)


1
mamiemando Messages postés 33772 Date d'inscription   Statut Modérateur Dernière intervention   7 882
 

C'est ce que je ferais aussi, par exemple à l'aide du module fasteners.

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > mamiemando Messages postés 33772 Date d'inscription   Statut Modérateur Dernière intervention  
 

Pourquoi utiliser un module, et pas simplement "open(ftemp, "x")"?

0
mamiemando Messages postés 33772 Date d'inscription   Statut Modérateur Dernière intervention   7 882 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 

Parce qu'open ne gère pas les accès concurrents (voir cette discussion).

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > mamiemando Messages postés 33772 Date d'inscription   Statut Modérateur Dernière intervention  
 

Le but ici est précisément d'avoir un accès exclusif...

0
mamiemando Messages postés 33772 Date d'inscription   Statut Modérateur Dernière intervention   7 882 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 

Bonjour yg_be,

Je reformule, car mon message précédent était ambigu. Avec open tu n'arriveras pas à mettre en place une lecture exclusive en cas d'accès concurrent.

Exemple :

#/usr/bin/env python3

filename = "/tmp/toto"
with open(filename, "w") as f1:
    print("1", file=f1)
    with open(filename, "w") as f2:
        print("2", file=f2)
print("3")

Résultat :

3

Contenu de /tmp/toto :

(mando@silk) (~) $ cat /tmp/toto  
1

Et tu noteras qu'aucune exception n'a été levée au moment de créer f2.
 

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 

bonjour,

si le programme ouvre le fichier en mode écriture, je pense que cela suffit pour empêcher une qu'un autre programme fasse de même.

0
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

Bonjour NHenry,

Oui, le verrou ça marche bien, et évidemment, avec MySql, pas de problème

Bonjour yg_be,

Non, j'utilise la vieille technique:

ouvrir le fichier en lecture

ouvrir un fichier temporaire en écriture

lire une ligne

si la ligne n'est pas à modifier, la copier telle quelle dans le fichier temp

sinon, copier la modif.

fermer les 2 fichiers

détruire le fichier original, renommer le fichier temp au nom du fichier original

J'avais fait ça en C dans le temps pour 25 utilisateurs, le problème, c'est qu'au bout d'un certain temps,

un utilisateur est venu me signaler que la base était dégradée: plus que 20 lignes au lieu de 100, du au

télescopage de plusieurs mises à jour en même temps

Comment faire? Pas évident avec la fonction standard C d'ouverture de fichier: f = fopen("test.txt", "w");

Mais au fait, les petits malins de chez Bill Gates n'auraient-ils pas créé leur propre fonction

(ou du moins un wrapper de la fonction standard ) ?

Bingo ! J'ai trouvé ce que j'ai affiché plus haut ...

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 

Pas compris, et il me semble pas logique d'avoit plusieurs fichiers temp en préparation en parallèle.
Encore moins d'avoir des programmes qui lisent un fichier en cours de remplacement.
Toutes des recettes qui ne peuvent conduire qu'à des problèmes.

0
Phil_1857 Messages postés 1872 Date d'inscription   Statut Membre Dernière intervention   168
 

Bonjour yg_be,

Comment ça pas compris ?

Il n'y a pas du tout plusieurs fichiers temp en préparation en parallèle

Comment fais tu pour modifier un fichier txt existant ? On ne peut pas l'ouvrir à la fois en lecture et en écriture

Moi, j'ai toujours fait comme ça:

open test.txt en lecture, temp.txt en écriture

lecture de test.txt ligne par ligne

si la ligne n'est pas à modifier, l'écrire dans temp.txt

si la ligne est à modifier, la modifier et l'écrire dans temp.txt

fermeture de test.txt, fermeture de temp.txt

détruire test.txt, renommer temp.txt en test.txt

"Encore moins d'avoir des programmes qui lisent un fichier en cours de remplacement."

Justement, avec le code en C que j'avais écrit dans le temps, la ligne que j'ai affichée plus haut permettait

d'attendre que le fichier soit libéré au cas ou quelqu'un d'autre aurait voulu y accéder

Donc un seul utilisateur à la fois pouvait le modifier: chacun son tour

Ca pétait le feu à la béquille ce truc

0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 

Moi je ferais ainsi:

  • boucler jusqu'à pouvoir créer temp.txt et en être l'utilisateur exclusif, en écriture
  • ouvrir test.txt en lecture
  • ...
  • fermeture de test.txt, fermeture de temp.txt
  • détruire test.txt, renommer temp.txt en test.txt
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
trauqnej Messages postés 154 Date d'inscription   Statut Membre Dernière intervention   23
 

Bonjour,
une méthode que j'utilise est de vérifier avec un fichier temporaire

filename = "/tmp/toto"
# tant que filename.temp existe alors filename est ouvert
import os
if os.path.exists("/tmp/fichier.temp"): 
	print("le fichier est ouvert.")
else:
	f = open('/tmp/fichier.temp','w')
	with open(filename, "w") as f1:
		print("ecriture", file=f1)
		
	os.remove("/tmp/fichier.temp")

print("sortie boucle")

Est-ce que cela répondrais à votre problématique ?

Cordialement,

0