Taille 'OnLine' d'une structure [Résolu]

Signaler
Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
-
Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
-
Bonjour,

Comme dit dans le titre, je cherche à connaitre le nombre d'octets d'une structure, de manière à estimer la taille du fichier txt dans lequelle son contenu sera transcrit.


Public Structure Voie
Dim IsActiv As Boolean 'Cet Item est actif
Dim Name As String
Dim ColorTray As Color
Dim HTray As Integer 'Epaisseur du trait
Dim ValFormat As Integer 'Format de la données (INT, REAL, BOOL)
Dim IsStepped As Boolean 'Representation en echelon ou extrapole
Dim OffsetH As Integer
Dim ScaleMax As Decimal 'Seuil Haut de la mise a l'echelle
Dim ScaleMin As Decimal 'Seuil Bas de la mise a l'echelle
Dim TimeRead() As Date
Dim ValRead() As Decimal
End Structure
Public ValReadOnLine As Voie

Ces deux derniers tableaux voient leur nombre d'indices s'incrémenter à chaque passage dans une boucle, il peuvent atteindre plusieurs dizaines de milliers:
Dim TimeRead() As Date
Dim ValRead() As Decimal

J'ai essayé:

VSize = Marshal.SizeOf(ValReadOnLine)


Mais la valeur n'évolue pas, j'imagine que cette fonction voit la taille native de la structure.

J'aurais aimé éviter les:

VSize = Ubound(ValReadOnLine.TimeRead) * 16
VSize += Ubound(ValReadOnLine.ValRead) * 8


Mais existe-t-il une autre solution?


Jimy

Pensez: Réponse acceptée
'**********************************************

5 réponses

Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Bonjour Jimy

Ces attributs servent à préciser que la structure sera séquentielle en mémoire, donc allouée en un seul bloc, et qu'elle est sérialisable.

Il est vrai que l'allocation séquentielle n'est pas importante ici car la structure possède des pointeurs (string, tableaux), donc il y aura de l'allocation dynamique qui ne peut être contiguë, on l'utilise principalement pour les structures de taille fixe, ce qui permet de l'envoyer sur un flux d'un seul bloc, et de connaitre précisément comment elle sera envoyée.

Personnellement je préfère la sérialisation, binaire ou XML, pour sauvegarder ou émettre des données.
Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
1
Houlala! Je vais m'employer à apprendre ce qu'est la sérialisation, car ceci dépasse ma compréhension, merci cs_Robert33.
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Bonjour

En passant par une sérialisation binaire ?

 Dim formatter As New BinaryFormatter
Dim ms As New MemoryStream()
Try
    formatter.Serialize(ms, ValReadOnLine)
    Console.WriteLine("Size :" & ms.Length)
Catch ex As SerializationException
    Console.WriteLine(ex.Message)
Finally
    ms.Close()
End Try

Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
il faut que ta structure soit sérialisable

    <StructLayout(LayoutKind.Sequential)> _
    <Serializable()> _
    Public Structure Voie
        ...
    End Structure
Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
1
Bonsoir cs_Robert33 et tout d'abord merci.

Je ne comprend pas bien cette syntaxe...

<StructLayout(LayoutKind.Sequential)> _
<Serializable()> _
Public Structure Voie
...
End Structure

Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
1
Je ne parviens pas à comprendre un point:
si "Ces attributs servent à préciser que la structure sera séquentielle en mémoire, donc allouée en un seul bloc, et qu'elle est sérialisable.", comment se gére l'accroissement de la structure à chaque redimensionnement?

Jimy

Pensez: Réponse acceptée
'**********************************************</signature>
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Les 2 attributs fonctionnent séparément.
-Le premier, <StructLayout(LayoutKind.Sequential)> indique que la structure sera séquentielle, donc en mémoire les champs seront alloués suivant l'ordre de déclaration, note que l'on peut définir d'autre Layout si l'on désire une représentation en mémoire différente. Mais cet attribut n'a aucun effet sur l'allocation dynamique des champs, comme les tableaux, en fait dans la structure ce seront des pointeurs de tableaux.
-Le deuxième,<Serializable()>, sert à la sérialisation, c'est une directive de pré-compilation. La sérialisation fait appelle à l'introspection de code, l'objet est analysé au runtime pour justement prendre en charge les champs dynamiques, comme les tableaux.

si tu utilises la sérialisation tu peux supprimer le premier attribut qui devient inutile, je l'avais mis par reflexe puisque c'était une structure, tu peux également utiliser "Class" à la place de structure cela donnera de meilleures performances.
Messages postés
834
Date d'inscription
samedi 15 novembre 2008
Statut
Membre
Dernière intervention
14 janvier 2017
30
Je te donne un exemple vite fait.
Je reprends ta structure
<Serializable()> _
Public Class Voie
    Public IsActiv As Boolean              'Cet Item est actif
    Public Name As String
    Public ColorTray As Color
    Public HTray As Integer                'Epaisseur du trait
    Public ValFormat As Integer            'Format de la données (INT, REAL, BOOL)
    Public IsStepped As Boolean            'Representation en echelon ou extrapole
    Public OffsetH As Integer
    Public ScaleMax As Decimal             'Seuil Haut de la mise a l'echelle
    Public ScaleMin As Decimal             'Seuil Bas de la mise a l'echelle  
    Public TimeRead() As Date
    Public ValRead() As Decimal
End Class

La fonction de sérialisation dans un fichier binaire
Sub Serialize()
    Using fs As New FileStream("SaveData.dat", FileMode.Create)
        Try
            Dim formatter As New BinaryFormatter
            formatter.Serialize(fs, ValReadOnLine)
        Catch ex As SerializationException
            Console.WriteLine(ex.Message)
        End Try
    End Using
End Sub


La fonction de dé-sérialisation du même fichier
Sub Deserialize()
    Using fs As New FileStream("SaveData.dat", FileMode.Open)
        Try
            Dim formatter As New BinaryFormatter
            ValReadOnLine = DirectCast(formatter.Deserialize(fs), Voie)
        Catch ex As SerializationException
            Console.WriteLine(ex.Message)
        End Try

    End Using

End Sub


un bout de test
ValReadOnLine.Name = "Test 123"
ValReadOnLine.TimeRead = Array.CreateInstance(GetType(Date), 5)
For i As Integer = 0 To 4
    ValReadOnLine.TimeRead(i) = Date.Now.AddDays(i)
Next
ValReadOnLine.ValRead = Array.CreateInstance(GetType(Decimal), 5)
For i As Integer = 0 To 4
    ValReadOnLine.ValRead(i) = i
Next

Serialize() ' on sauvegarde
ValReadOnLine = Nothing 'juste pour voir si on récupère bien
Deserialize() 'on récupère
' sous débugger tu peux vérifier les données
Messages postés
491
Date d'inscription
mercredi 1 février 2006
Statut
Membre
Dernière intervention
18 novembre 2016
1
Je tiens à te remercier pour ton aide et la clarté de tes explications! Merci! ;)