IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Lecture d'un fichier situé sur un ordinateur distant occasionnant un résultat aléatoire


Sujet :

VB.NET

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Points : 32
    Points
    32
    Par défaut Lecture d'un fichier situé sur un ordinateur distant occasionnant un résultat aléatoire
    Bonjour à tous
    Je fais appel à la communauté car j'ai un problème concernant la mise en commun de données entre 2 ordinateurs.

    Concrètement, j'ai un Raspberry-Pi qui me permet de mesurer des paramètres ambiants à l'aide de différents capteurs (température, hygrométrie, pression atmosphérique, point de rosée). Un logiciel développé sur le RPI se charge des acquisitions à la fréquence d'une mesure toutes les 30s. Afin de pouvoir récupérer les valeurs via un programme en VB.NET qui tourne sur un PC, le programme sur le RPI met à jour un fichier .txt contenant les valeurs mesurées. Toutes les 30s, une ligne contenant l'heure et les 3 valeurs mesurées s'ajoute au fichier. Au delà d'une certaine taille (2Ko), le fichier est recréé, de manière à éviter la saturation dans le stockage du RPI.

    Exemple d'un des fichiers correspondant à un capteur type DHT22 :
    Temp, Hum, Rosee 14-03-2020 18h38m39s/25.3/32.5/7.6/
    Temp, Hum, Rosee 14-03-2020 18h39m09s/25.3/32.4/7.6/
    Temp, Hum, Rosee 14-03-2020 18h39m39s/25.3/32.4/7.6/

    De ce coté, tout va bien, le fichier généré est mis à jour en permanence sans écueil. J'ai donné les droits d'accès au fichier à l'aide de Samba et tous les ordinateurs du réseau accèdent au fichier qui se met à jour. Une ouverture manuelle permet de visualiser le contenu à jour.

    Coté PC, un programme en VB.NET va ouvrir le fichier stocké sur le RPI à raison d'une scrutation par minute. Vu que je fait des courbes sur 24h, cette valeur d'échantillonnage est suffisante. Je récupère la dernière ligne du fichier pour en récupérer les différentes données et les mettre en forme à l'aide d'un graphique.

    Et c'est là que le bât blesse. Le programme ne récupère pas systématiquement pas la dernière version du fichier à jour. Lorsque je lance le programme, je récupère bien la dernière version du fichier stocké sur le RPI, mais après, l'ouverture du fichier à la dernière version devient complètement aléatoire. J'ai comme l'impression que le programme VB.NET conserve une version du fichier en mémoire et se "contente" d'ouvrir cette version et pas la version à jour physiquement disponible sur le RPI.

    J'ai testé différentes méthodes pour ouvrir le fichier et récupérer le contenu, mais dans tous les cas, l’ouverture du fichier à jour est aléatoire. Lorsque je teste le programme en mode pas à pas, je n'ai aucun problème, le fichier à jour sur le RPI est bien traité. Dès que le programme tourne en continu (1 lecture à la minute !), la mise à jour des données ne s'effectue pas et je récupère des valeurs non à jour.

    Méthode 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    FSO = CreateObject("Scripting.FileSystemObject")
    TxtStream = FSO.OpenTextFile("\\RPI2_CAPTEURS\Documents\DHT22I.txt", 1)
    V_Param = TxtStream.ReadAll
    FSO = Nothing
    Méthode 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Dim SR As StreamReader = File.OpenText("\\RPI2_CAPTEURS\Documents\DHT22I.txt")
    Do Until SR.Peek = -1
    V_Param = SR.ReadLine()
    Loop
    Histoire de ne pas rester sur cet échec (qui sera résolu grâce à vous, je n'en doute pas), j'ai fait un test qui constitue non pas à ouvrir directement le fichier du RPI chaque minute, mais à le copier et à le coller sur le disque dur du PC sur lequel tourne le programme en VB.NET. La méthode pour ouvrir le fichier et récupérer le contenu est identique à l'action précédente, à part le chemin du fichier à ouvrir. J'ai juste intercalé quelques lignes de programme pour transférer le fichier.

    Et là, aucun problème pour récupérer les données à jour, tout fonctionne à merveille.

    Sur la courbe qui en résulte, voilà ce que ça donne. Pour la température et la pression atmo, on voit bien qu'avant 19h00, la mise à jour des valeurs est aléatoire. A 19h00, je modifie le programme qui consiste à transférer le fichier du RPI vers le PC. Et là, tout est bon.
    PS : la courbe verte (point de rosée) provient d'un autre capteur qui est connecté directement sur le PC.

    Nom : Courbe DHT.jpg
Affichages : 149
Taille : 41,3 Ko

    Voilà, mes explications sont un peu longues mais j'ai essayé de décrire aussi précisément que possible mon problème.

    Merci de m'avoir lu et si vous avez une explication sur le problème posé, et surtout une solution, je suis à votre écoute.

    Jean-Pierre

  2. #2
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Bonjour Discret

    Le problème vient probablement de l'absence d'un Close ou d'un Flush.
    Je te propose d'ajouter dans tes codes, sur tous les PC (local ou distants), l'instruction Flush tout de suite après une séquence d'écriture vers un fichier.

    Lorsque nous travaillons avec des fichiers, nous programmons des ordres Open, Close, Read, Write, Seek, ... et nous voyons cela comme des actions directes sur les mémoires de masse. Or, nous ne faisons que converser avec le système d'exploitation qui traite les mémoires de masse "à sa mode", "quand il en a le temps".
    La conséquence de cela en matière d'écriture vers le fichier est la suivante :
    • Le système s'est réservé un buffer de sortie vers le fichier;
    • Un ordre d'enregistrement écrit dans ce buffer;
    • Quand le buffer est plein, et au plus tard quand on ferme le fichier, le système transfert effectivement les données vers la mémoire de masse.

    Il s'en suit que si tu lis le fichier alors que les 2 derniers enregistrements (par exemple) sont toujours dans le buffer, tu ne les récupères pas.

    Donc, la solution est de forcer l'OS à vider son buffer vers le fichier. Cela se fait en fermant le fichier (et en le rouvrant si nécessaire), ou mieux en utilisant l'instruction Flush lorsqu'elle existe.

    J'espère que ceci t'aidera ....


  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Points : 32
    Points
    32
    Par défaut
    Bonjour Phil. Toujours sur le pont à ce que je constate

    Le fichier étant créé sur un Raspberry Pi en Python, je ne peux pas utiliser la méthode Flush à ce niveau. Et du coté création/mise à jour du fichier, aucun soucis.

    Coté PC avec le programme en VB.NET, je suis en lecture uniquement du fichier .txt. D'après les différents articles sur le net, et vu ce qu'il me semble avoir compris, la méthode Flush est plutôt utilisée lors de l'écriture d'un fichier via un StreamWriter.

    La méthode associée au StreamReader semble plutôt être DiscardBufferedData qui permet d'effacer le contenu du buffer. J'ai donc rajouté cette méthode dans mon programme après la lecture du fichier, qui se fait à nouveau directement sur le Raspberry Pi. Cela fait 7h que le programme est en service et à priori, tout est OK, les valeurs sont bien rafraichies à chaque ouverture du fichier (1 fois par minute).

    Le code résultant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                Dim V_Param As String
                V_Param = ""
                Dim SR As StreamReader = File.OpenText("\\RPI2_CAPTEURS\Documents\BME280.txt")
                Do Until SR.Peek = -1
                    V_Param = SR.ReadLine()
                Loop
                SR.Close()
                SR.DiscardBufferedData()
    Je vais laisser le programme tourner un certain temps et si tout se passe correctement, je passerai la discussion en résolu.

    Merci à toi pour ton aide.

    JP

  4. #4
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Bonsoir,

    Comme je vois ton code, ta méthode SR.DiscardBufferedData() ne sert pas à l'obtention des données, tu l’utilises d'ailleurs, sur le fichier fermé, lecture terminée.
    Ton problème ne peut disparaître avec ce code.

    Le problème du buffer non vider vers le fichier est effectivement un problème d'écriture du fichier et lorsqu'on ne dispose pas d'un Flush, on pratique un fermeture du fichier immédiatement suivie de la réouverture du fichier.

    C'est le Raspberry qui écrit le fichier et c'est dans son langage que tu dois trouver l'équivalent du Flush ou programmer la fermeture du fichier après un enregistrement et le rouvrir avant l'enregistrement suivant.
    A voir : https://www.tutorialspoint.com/python/file_flush.htm

    Attention qu'il ne s'agit pas de "vider" le buffer, mais bien de "forcer l'enregistrement" de son contenu dans le fichier.

    Bon travail,

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Points : 32
    Points
    32
    Par défaut
    Bonsoir Phil
    Si la méthode DiscardBufferedData a pour vertu de vider le buffer à la lecture des données, quelle différence à vider le buffer avant la lecture d'une fichier ou après lecture du fichier, ce qui en fait prépare la nouvelle ouverture du fichier ?

    Néanmoins, le fait d'avoir ajouté cette ligne dans le programme VB a permis d'avoir une lecture des données à jour. La courbe qui résulte de l'ouverture du fichier qui est enregistré sur le Raspberry Pi semble le démontrer :

    Nom : Courbe BME1.jpg
Affichages : 114
Taille : 24,0 Ko

    Suite à ton dernier message, j'ai pris en compte la méthode Flush dans le programme du RPI :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          Texte = 'Temp, press ' + str(HeureActuelle) + " /" + str('{0:0.1f}' .format(temperature)) +"/"+ str('{0:0.1f}' .format(pressure))+'/'+ str('{0:0.1f}' .format(humidite))+'/'+'\n'
          fichier = open('/home/pi/Documents/BME280.txt','a')
          fichier.write (Texte)
          fichier.flush()
          fichier.close()
    Au niveau du programme VB sur le PC, j'ai supprimé la méthode DiscardBufferedData et je suis revenu au programme d'origine pour l'ouverture du fichier en direct sur le RPI, programme qui posait problème au départ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                Dim V_Param As String
                V_Param = ""
                FSO = CreateObject("Scripting.FileSystemObject")
                TxtStream = FSO.OpenTextFile("\\RPI2_CAPTEURS\Documents\BME280.txt", 1)
                V_Param = TxtStream.ReadAll
                Call TxtStream.Close()
                FSO = Nothing
    Au final, le fait est que la lecture du fichier se fait également avec la bonne mise à jour des données.
    Nom : Courbe BME2.jpg
Affichages : 118
Taille : 26,4 Ko

    JP

  6. #6
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Bonjour JP,

    Si ça marche, c'est le principal ...

    Mais voici pour ton infirmation :
    Si la méthode DiscardBufferedData a pour vertu de vider le buffer à la lecture des données, quelle différence à vider le buffer avant la lecture d'une fichier ou après lecture du fichier, ce qui en fait prépare la nouvelle ouverture du fichier
    Ta remarque est parfaitement justifiée et effectivement, là, avant ou après ne change rien.
    Mais " vider le buffer à la lecture des données" n'a pas de sens en rapport avec ton problème. Comme je te l'indiquais dans le message précédent, il s'agit de force le système à enregistrer physiquement les données sur la mémoire de masse. Quand tu lis le fichier, ton programme demande au système de ramener les données de la mémoire de masse, et non du buffer du programme qui a écrit ces données (quant bien même ce serait le même programme : le buffer alloué à la lecture n'est pas le même que celui alloué à l'écriture).

    Donc tu as trouvé un Flush que tu places tout de suite après l'écriture du fichier : c'est exactement ce qu'il faut.

    L'exemple que tu donnes, c'est du VB (n'est-ce pas ?). J'espère que peux placer ce Flush aussi dans les commandes du Raspberry.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          fichier = open('/home/pi/Documents/BME280.txt','a')
          fichier.write (Texte)
          fichier.flush()
          fichier.close()
    Le code de ton exemple garantit que la dernière donnée enregistrée est immédiatement disponible pour toute lecture. Ce code est même "trop fort".
    En effet, si tu fais un Close tout de suite après l'écriture, le Flush n'est plus nécessaire, le Close force le système à enregistrer physiquement les données (c'est bien connu qu'il ne faut pas oublier de fermer un fichier ouvert en écriture, et c'est bien pour forcer l'enregistrement des dernières données).
    Le Flush est indispensable lorsqu'on ne ferme pas le fichier à chaque enregistrement et qu'on relis tout de même les données entre-temps. Je suppose que le Raspberry mis en fonction ouvre le ficher et ne le ferme que lorsqu'on arrête son fonctionnement, et que c'est pour ça qu'on ne dispose pas toujours des dernières données.

    Tu peux imaginer le buffer en écriture comme un réservoir d'eau qui se laisse remplir petit à petit et qui se vide d'un seul coup quand la dernière "goutte" est arrivée. Mais seul le gestionnaire du réservoir sait quand c'est la dernière goutte. Par contre nous avons le pouvoir de forcer ce gestionnaire à vider le réservoir de deux manières : en fermant l'arrivée d'eau (Close) ou en poussant le bouton "vidange d'urgence" ('Flush).

    J'espère que tout ce bla-bla ne te saoulera pas ...

    Bonne journée,

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Astronome amateur
    Inscrit en
    Juillet 2016
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Astronome amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 63
    Points : 32
    Points
    32
    Par défaut
    Hello Phil

    Le bout de code, qui contient le Flush, et que j'ai mis dans mon dernier message se trouve dans le programme en python qui tourne sur le Raspberry Pi.

    Le fait est que dorénavant, le transfert de données entre les 2 ordis (RPI et PC) se déroule sans anicroche, et c'était le but recherché.

    Rassures toi, tes propos ne me saoulent pas et je les bois jusqu'à la lie

    Merci encore à toi pour ton aide, et à un prochain problème ....

    Bien cordialement

    Jean-Pierre

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture des fichiers situé sur le poste serveur
    Par junior222 dans le forum JWS
    Réponses: 0
    Dernier message: 29/08/2015, 14h09
  2. impression d'un fichier situé sur le serveur
    Par Phiss dans le forum ASP
    Réponses: 6
    Dernier message: 21/06/2007, 14h48
  3. Acces a des fichiers situes sur une autre machine
    Par vsevel dans le forum Glassfish et Payara
    Réponses: 2
    Dernier message: 19/06/2007, 17h23
  4. Réponses: 2
    Dernier message: 31/07/2006, 16h26
  5. Réponses: 6
    Dernier message: 23/02/2006, 12h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo