Tester si un fichier est déjà ouvert

Résolu/Fermé
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 - Modifié le 9 juil. 2022 à 11:12
trauqnej Messages postés 154 Date d'inscription mardi 7 juin 2005 Statut Membre Dernière intervention 5 septembre 2022 - 3 août 2022 à 03:44

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 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
9 juil. 2022 à 12:07

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 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 7 749
12 juil. 2022 à 23:36

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

0
yg_be Messages postés 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024 1 477 > mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024
14 juil. 2022 à 20:31

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

0
mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 7 749 > yg_be Messages postés 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024
15 juil. 2022 à 03:33

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

0
yg_be Messages postés 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024 1 477 > mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024
15 juil. 2022 à 12:08

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

0
mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 7 749 > yg_be Messages postés 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024
Modifié le 18 juil. 2022 à 14:01

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 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024 1 477
9 juil. 2022 à 13:54

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 9 juil. 2022 à 18:08

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 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024 1 477
9 juil. 2022 à 22:22

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 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
10 juil. 2022 à 10:49

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 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024 1 477
10 juil. 2022 à 14:07

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 mardi 7 juin 2005 Statut Membre Dernière intervention 5 septembre 2022 23
3 août 2022 à 03:44

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