[.net] i/o type/structure (compatibilité vb6)

Soyez le premier à donner votre avis sur cette source.

Snippet vu 11 172 fois - Téléchargée 35 fois

Contenu du snippet

Ok le titre n'est pas tres explicite, j'explique :

Pour ceux qui travail avec les fichiers en VB.NET il est devenue assez complexe de lire et d'ecrire dans les fichiers des Structures predefinis (en VB6 il suffisait de definir son Type puis d'utiliser Put # et Get #) alors j'ai cherché pendant un bon moment pour trouver la solution idéal. Faute d'avoir trouvé l'idéal... voici la methode la plus efficace pour le moment dont je vous livre le contenue :

( 1 ) - Premierement transcrire la structure en syntaxe VB.NET (petit rappel)

- - Dim I As Long => Dim I As Int
- - Dim I As Integer => Dim I As Short
- - Etc...
- - Dim I As String * 8 =>
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _
Dim I As String

- - Dim I(7) As Byte =>
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> _
Dim I() As Byte
Sub New(ByVal e)
ReDim Test2(8-1)
End Sub

( 2 ) - Ajouter les fonctions ByteToStruct(Typé) & StructToByte
- - Modifier chaque fonction ByteToStruct pour accepter le type voulue

( 3 ) - Lire et/ou ecrire avec un FileStream standard
- - Une fois que l'on a converti la structure en tableau d'octet on peut
- - lire et ecrire a volonté...

Source / Exemple :


Option Explicit On 

Imports System.Runtime.InteropServices

    Private Structure TYPETEST
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _
        Dim Test1 As String
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> _
        Dim Test2() As Byte
        Sub New(ByVal e)
            ReDim Test2(7)
        End Sub
    End Structure

    Private Function ByteToStruct(ByRef Data() As Byte) As Object
        Dim Handle As GCHandle = GCHandle.Alloc(Data, GCHandleType.Pinned)
        Dim Pointer As IntPtr = Handle.AddrOfPinnedObject()
        ByteToStruct = DirectCast(Marshal.PtrToStructure(Pointer, GetType(TYPETEST)), TYPETEST)
        Handle.Free()
    End Function

    Private Function StructToByte(ByRef Obj As Object) As Byte()
        Dim Data(Marshal.SizeOf(Obj)) As Byte
        Dim Handle As GCHandle = GCHandle.Alloc(Data, GCHandleType.Pinned)
        Dim Pointer As IntPtr = Handle.AddrOfPinnedObject()
        Marshal.StructureToPtr(Obj, Pointer, False)
        Handle.Free()
        Return Data
    End Function

   Private Sub OnWrite()
        Dim vTest As New TYPETEST(0)
        Dim vData() As Byte
        With New IO.FileStream("Test.txt", IO.FileMode.OpenOrCreate)
            vTest.Test1 = "Manu"
            vData = StructToByte(vTest)
            .Write(vData, 0, vData.Length)
            .Close()
        End With
    End Sub

    Private Sub OnRead()
        Dim vTest As New TYPETEST(0)
        Dim vData() As Byte
        With New IO.FileStream("Test.txt", IO.FileMode.Open)
            .Read(vData, 0, vData.Length)
            vTest = ByteToStruct(vData)
            .Close()
        End With
    End Sub

Conclusion :


Voila c'est une methode farfelu pour pas grand chose si qlq1 a une solution plus radicale pour lire et ecrire des structures avec des chaine/tableau de longueur fixe merci de partagé votre savoir ;)

Le petit plus c'est biensur la methode de copie de données brut qui marche avec n'importe quel objet, tableau ou variable dont je ferais peut etre un autre exemple plus tard

B@nne prog

A voir également

Ajouter un commentaire Commentaires
Messages postés
256
Date d'inscription
jeudi 23 octobre 2003
Statut
Membre
Dernière intervention
20 mars 2013
1
Bonjour EBArtSoft,

J'essaie d'utiliser ton code pour une application légèrement différente, en effet, j'ai 2 PC qui dialogue par Socket (cette partie là c'est bon) !
Le PC n°1 récupère des éléments dans une BdD, les stockes dans une structure et les envoie au PC n°2.
Tout est bon si ce n'est la sérialisation avant l'envoi !
Ma structure se limite à un tableau à 40 colonnes et à N lignes et les données peuvent être des entiers, text, ...

Comment dois-je utiliser ton code et définir les différents éléments pour que cela fonctionne avec ce que je suis en train de faire ?

Par avance merci

Olivier

PS : c'est malheureusement urgent !
Messages postés
119
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
28 avril 2008

Pour les intéressés, j'ai enfin réussi, après 3 semaines de galères, à écrire 5 enregistrements (5 structures) de taille variable dans un un fichier binaire :

http://www.vbfrance.com/codes/SERIALISATION-DESERIALISATION-STRUCTURE_41077.aspx

Ça marche aussi pour les objets.
Messages postés
467
Date d'inscription
lundi 24 juin 2002
Statut
Membre
Dernière intervention
9 mars 2011

>
De plus tous les exemples vus montre comment (dé)sérialiser UN seul objet. Mais quand tu en a plusieurs dans un fichier et chacun de taille différente, comment fait-on ? <==

Lool ? c'est un piègre ta question ? Sinon je vais te poser une 2ieme question tu connais les "tableau", "collection" ? ba tu serializes ta collection de structure et quand tu deserialize tu retrouve tout
Messages postés
119
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
28 avril 2008

J'ai résolu l'erreur, mais pas le warning :

.Read(vData, 0, vData.Length)

Et à l'exécution une exception est levée. Si tu as une idée, d'avance merci.
Messages postés
119
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
28 avril 2008

Merci pour ta promptitude ! mais j'arrive plus à faire marcher ton programme. J'ai ouvert un projet vide avec un fichier vide et j'ai tapé ceci (en VB.Net sous SharpDevelop) :

Option Explicit On

Imports System.Runtime.InteropServices

Public Class Struct

Public Sub main()
OnWrite()
OnRead()
End Sub

(ton code)
End class

1 erreur : Aucune méthode main accessible avec une signature appropriée n'a été trouvé dans Essai (nom de mon projet)

1 warning (ligne 46 de ton code): .Read(vData, 0, vData.Length) -> vdata est utilisée avant qu'une valeur ne lui a été assignée.

Tu vois quel est le problème ?
Afficher les 33 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.