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
20 sept. 2012 à 16:10
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 !
12 janv. 2007 à 13:13
http://www.vbfrance.com/codes/SERIALISATION-DESERIALISATION-STRUCTURE_41077.aspx
Ça marche aussi pour les objets.
12 janv. 2007 à 10:45
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
11 janv. 2007 à 11:54
.Read(vData, 0, vData.Length)
Et à l'exécution une exception est levée. Si tu as une idée, d'avance merci.
10 janv. 2007 à 15:25
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 ?
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.