OVH Cloud OVH Cloud

WRITE et sauvegarde sur disque

3 réponses
Avatar
Jacquelin Hardy
Bonjour,

lorsque je me sers de l'instruction WRITE pour enregistrer du texte
dans un fichier, ce texte semble être en mémoire seulement jusqu'à ce
que je termine l'application, ie. pas de sauvegarde sur disque jusqu'à
la fermeture. Est-ce que c'est vraiment ça qui se passe ? Et si oui,
comment forcer une sauvegarde (quelle instruction) à des intervalles
donnés avec un TIMER ? Faut-il que je CLOSE la FreeFile à chaque fois
que je veuille sauver sur disque et la réouvrir aussitôt pour continuer
à accumuler ce que je veux enregistrer ?

Merci

Jacquelin Hardy

3 réponses

Avatar
Jean-marc
Jacquelin Hardy wrote:
Bonjour,

lorsque je me sers de l'instruction WRITE pour enregistrer du texte
dans un fichier, ce texte semble être en mémoire seulement jusqu'à ce
que je termine l'application, ie. pas de sauvegarde sur disque jusqu'à
la fermeture. Est-ce que c'est vraiment ça qui se passe ? Et si oui,
comment forcer une sauvegarde (quelle instruction) à des intervalles
donnés avec un TIMER ? Faut-il que je CLOSE la FreeFile à chaque fois
que je veuille sauver sur disque et la réouvrir aussitôt pour
continuer à accumuler ce que je veux enregistrer ?



Hello,

Les fonctions sur les fichiers sont bufferisées, ça veut dir que chaque
instruction Write, Put, etc. ne réalise pas une écriture physique sur
le disque, mais que les données sont écrites dans une zone mémoire tampon.
Seulement quand le buffer a une certaine taille, un accès physique est
fait et les données écrites.

L'instruction Close force l'écriture sur disque et la fermeture du fichier.
http://msdn2.microsoft.com/en-us/library/aa243283(vs.60).aspx

C'est toujours (ou presque) une mauvaise habitude ou un mauvais design de
garder un fichier ouvert en écriture plus que de raisons.

Si ton application est très spéciale et doit faire énormément de write, à un
rythme soutenu, avec de grosses contraintes de performances, il faut tout de
même (à définir selon le niveau de sécurité que tu souhaites) fermer et
réouvrir
à intervalle régulier.

Si ton appli n'a pas ces contraintes, la règle est:
j'ouvre, j'écris, je ferme.

Si ce modèle ne te convient pas, tu peux utiliser les fonctions bas
niveau de l'API Windows (CreateFile, etc.) pour gérer tes fichiers.
Tu disposes alors de la fonction FlushFileBuffers qui permet de forcer
l'écriture à tout moment, sans devoir fermer.

Evidemment, c'est un peu plus compliqué à utiliser:

http://msdn2.microsoft.com/en-us/library/aa363858.aspx
http://msdn2.microsoft.com/en-us/library/aa364439.aspx
http://support.microsoft.com/kb/165942/en-us


--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/
Avatar
Jacquelin Hardy
Merci Jean-Marc,

>Si ton appli n'a pas ces contraintes, la règle est:
> j'ouvre, j'écris, je ferme

J'enregistre des données dynamiques de positionnement GPS et des
données d'un navire (300 octets environ), comme l'écart de sa route (XTE
cross track error), une fois par seconde et d'autres données provenant
de navires (AIS data)dans le voisinnage qui entre à 38400 bauds, de
façon aléatoires, environ 25 octets par navire par message. Plus de
navires, plus de données. Irais-tu avec la règle > j'ouvre, j'écris, je
ferme< ou bien une fois à toutes les minutes ou moins souvent encore,
comme 15 minutes ou 1 heure.

Et pendant ce temps-là je dois afficher sur écran les données du
navire, son positionnement et celui des contacts, et redessiner la carte
au besoin si le navire arrive près du centre. Le CPU roule à 8% de sa
capacité normalement et monte à 70% pour une fraction de seconde quand
la carte est redessinée (carte vectorielle dessinée avec des API's comme
polypolygones surtout)

Je te remercie encore pour ton temps et ta disponibilité

Jacquelin Hardy


Jean-marc a écrit :
Jacquelin Hardy wrote:
Bonjour,

lorsque je me sers de l'instruction WRITE pour enregistrer du texte
dans un fichier, ce texte semble être en mémoire seulement jusqu'à ce
que je termine l'application, ie. pas de sauvegarde sur disque jusqu'à
la fermeture. Est-ce que c'est vraiment ça qui se passe ? Et si oui,
comment forcer une sauvegarde (quelle instruction) à des intervalles
donnés avec un TIMER ? Faut-il que je CLOSE la FreeFile à chaque fois
que je veuille sauver sur disque et la réouvrir aussitôt pour
continuer à accumuler ce que je veux enregistrer ?



Hello,

Les fonctions sur les fichiers sont bufferisées, ça veut dir que chaque
instruction Write, Put, etc. ne réalise pas une écriture physique sur
le disque, mais que les données sont écrites dans une zone mémoire tampon.
Seulement quand le buffer a une certaine taille, un accès physique est
fait et les données écrites.

L'instruction Close force l'écriture sur disque et la fermeture du fichier.
http://msdn2.microsoft.com/en-us/library/aa243283(vs.60).aspx

C'est toujours (ou presque) une mauvaise habitude ou un mauvais design de
garder un fichier ouvert en écriture plus que de raisons.

Si ton application est très spéciale et doit faire énormément de write, à un
rythme soutenu, avec de grosses contraintes de performances, il faut tout de
même (à définir selon le niveau de sécurité que tu souhaites) fermer et
réouvrir
à intervalle régulier.

Si ton appli n'a pas ces contraintes, la règle est:
j'ouvre, j'écris, je ferme.

Si ce modèle ne te convient pas, tu peux utiliser les fonctions bas
niveau de l'API Windows (CreateFile, etc.) pour gérer tes fichiers.
Tu disposes alors de la fonction FlushFileBuffers qui permet de forcer
l'écriture à tout moment, sans devoir fermer.

Evidemment, c'est un peu plus compliqué à utiliser:

http://msdn2.microsoft.com/en-us/library/aa363858.aspx
http://msdn2.microsoft.com/en-us/library/aa364439.aspx
http://support.microsoft.com/kb/165942/en-us




Avatar
Jean-marc
Jacquelin Hardy wrote:
Merci Jean-Marc,

Si ton appli n'a pas ces contraintes, la règle est:
j'ouvre, j'écris, je ferme



J'enregistre des données dynamiques de positionnement GPS et des
données d'un navire (300 octets environ), comme l'écart de sa route
(XTE cross track error), une fois par seconde et d'autres données
provenant de navires (AIS data)dans le voisinnage qui entre à 38400
bauds, de façon aléatoires, environ 25 octets par navire par message.
Plus de navires, plus de données. Irais-tu avec la règle > j'ouvre,
j'écris, je ferme< ou bien une fois à toutes les minutes ou moins
souvent encore, comme 15 minutes ou 1 heure.



Alors moi je ferais comme ça: Je ferais une procédure WriteData, avec
une variable statique pour fermer/réouvrir le fichier toutes les X
écritures. Ca donnerait ça:

Const FORCE_WRITE_THRESHOLD As Long = 10

Private Sub WriteData(ByVal fileName As String, _
ByRef fileHandle As Integer, _
ByVal data As String)

Static cptWrite As Long

cptWrite = cptWrite + 1

' FORCE_WRITE_THRESHOLD est une constante;
' on va en re parler plus loin
'
If cptWrite > FORCE_WRITE_THRESHOLD Then
cptWrite = 0
Close #fileHandle
fileHandle = FreeFile
Open fileName For Append As #fileHandle
End If
Write #fileHandle, data
End Sub

Et pour l'utilisation, comme ça:


Dim i As Integer, fname As String
Dim f As Integer, data As String

fname = "c:aa.dat"

f = FreeFile
Open fname For Output As #f
data = "DATA TEST DATA TEST DATA TEST"
For i = 1 To 100
Call WriteData(fname, f, data)
Next i
Close #f

Il ne te reste plus qu'à mettre
FORCE_WRITE_THRESHOLD à une valeur qui te convienne;
Disons que ton appli enregistre des données une fois par
seconde, combien de secondes peux tu accepter de perdre en
cas de crash ?

Moi je dirais que si tu fixes FORCE_WRITE_THRESHOLD à 10,
c'est un bon compromis.

De toute façon, vu les très faibles volumes de données à
enregistrer chaque seconde (pas plus de qq milliers d'octets),
le close/open ne sera même pas couteux.

Donc oui, je dirais 10 pour commencer, et même le baisser à 5.
A toi de faire qq mesures, mais je mets ma main à couper que tu
ne verras aucune augmentation de la charge CPU et que ça ne changera pas
d'un iota le comportement de ton appli (même à 5).

--
Jean-marc Noury (jean_marc_n2)
Microsoft MVP - Visual Basic
mailto: remove '_no_spam_' ;
FAQ VB: http://faq.vb.free.fr/