Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016
-
31 août 2004 à 20:17
guilleto
Messages postés256Date d'inscriptionjeudi 23 octobre 2003StatutMembreDernière intervention20 mars 2013
-
20 sept. 2012 à 16:10
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
guilleto
Messages postés256Date d'inscriptionjeudi 23 octobre 2003StatutMembreDernière intervention20 mars 20131 20 sept. 2012 à 16:10
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 !
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 12 janv. 2007 à 13:13
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 :
TeBeCo
Messages postés467Date d'inscriptionlundi 24 juin 2002StatutMembreDernière intervention 9 mars 2011 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
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 11 janv. 2007 à 11:54
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.
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 10 janv. 2007 à 15:25
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 ?
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 10 janv. 2007 à 12:43
_Fabien> Le "byval e" ne sert a rien cela dit pour pouvoir ecrire une fonction de constructeur "New" il faut definir des argument donc voila pourquoi "ByVal e". Deuxiemement c'est normal que tu lise Manu puisque le premier membre de la structure est du type String donc le debut du fichier sera lisible compte tenu qu'on lui a affecté une valeur lisible : vTest.Test1 = "Manu"
@+
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 10 janv. 2007 à 12:14
Salut EBArtSoft,
Je suis en train d'examiner et de comprendre ton code. Je suis débutant. J'ai un certain nombre de questions à te poser :
- ligne 10 : à quoi sert le "ByVal e" et pourquoi tu ne lui as pas attribué un type ?
- Sinon, je m'attendais à voir dans le fichier "Test.txt", un truc illisible du genre "!%dff" (comme en C quand on écrit en binaire), mais c'est du texte ("Manu"). Signifie-t'il que ce n'est pas en binaire que tu écris dans ton fichier "Test.txt" ?
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 10 janv. 2007 à 11:41
Voici un exemple de sérialisation d'un objet en passant par le XML (sympa pour les débutants :) :
N'empêche que c'est vraiment tordu d'écrire une struture dans un fichier binaire en VB.Net.
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 ?
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 8 janv. 2007 à 19:24
C'est le même problème avec les Structure pour le Midi ?
Yop
Afyn - Navedac
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 7 janv. 2007 à 13:20
TeBeCo>
Premierement : Ce n'est par ce que je ne presente que des sources en vb6 que je ne connais pas le .net
Deuxiement : As-tu deja observé un fichier généré par la methode BinaryFormatter.Serialize ?
Biensur que tu peux sauvegarder ton objet mais la on parle de structure dont l'odre des données binaire est bien definis ! Hors quand tu utilises la serialisation tu enregistres en plus des données les informations necessaire a la recuperation de ces dites données. Par consequent tu n'enregistres pas au format voulue. Relis les commentaires plus haut et tu comprendra de quelle type de données on parle.
Aller un petit exemple imaginons que je veux faire un lecteur de fichier TAR en .NET. Mon but lire les entrés de l'archive une par une. En vb6 ou en C je crée une structure que je lit en une seule ligne de code elle ressemble a ceci :
Public Type TARHEADER
Name As String * NAMSIZ
Mode As String * 8
Uid As String * 8
Gid As String * 8
Size As String * 12
mtime As String * 12
ChkSum As String * 8
Linkflag As String * 1
Linkname As String * NAMSIZ
Magic As String * 8
Reserved(246) As Byte
End Type
Maintenant comment faire en .NET ? Voila c'est pas compliqué. Par contre même en definissant un objet aux proprietés identiques je ne peux pas deserialiser directement dans l'archive TAR. Que me proposes tu ?
@+
TeBeCo
Messages postés467Date d'inscriptionlundi 24 juin 2002StatutMembreDernière intervention 9 mars 2011 6 janv. 2007 à 21:36
(si je pouvais éditer mon msg je virerais le "de faire" a l'avant derniere ligne
TeBeCo
Messages postés467Date d'inscriptionlundi 24 juin 2002StatutMembreDernière intervention 9 mars 2011 6 janv. 2007 à 21:35
Mélange pas la serialization et SQL ca a absolument rien a voir certes on peut les utiliser enssemble mais sans aucun lien de rapprochement plus concret
La serialization se fait soit au format XML soit Binaire
Ca se fait avec TRES PEU de ligne de code et tu peux serializé 90% des objet .net sans difficulté ni code a rajouté les 10% restant reste serializable mais ya un poil de code en plus a faire et pour tout les type dont t'as parlé plus haut je vois 0 difficulté ca doit passer en 5 ligne pour appeler le serializer (avec de la marge) et peut etre 8 a la recup
ca reste qu'une question de faire de motivation et faire l'effort une fois passer a .net d'utilisé des outils adapté et non pas ce qu'on a l'habitude de faire
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 6 janv. 2007 à 11:49
EBArtSoft , tu pourrais pas essayer avec çà ;-P.
J'abuse. Je n'ai toujours pas essayé avec ta méthode, mais bientôt :)
Public Structure HighScore
' attributs
Private _pseudo As String
Private _score As Integer
Private _reussite As Double
Private _duree_jeu As TimeSpan
' propriétés
Public Property pseudo() As String
Get
Return _pseudo
End Get
Set(ByVal value As String)
_pseudo = value
End Set
End Property
Public Property score() As Integer
Get
Return _score
End Get
Set(ByVal value As Integer)
_score = value
End Set
End Property
Public Property reussite() As Double
Get
Return _reussite
End Get
Set(ByVal value As Double)
_reussite = value
End Set
End Property
Public Property duree_jeu() As TimeSpan
Get
Return _duree_jeu
End Get
Set(ByVal value As TimeSpan)
_duree_jeu = value
End Set
End Property
' Constructeur
Public Sub New(ByVal __pseudo As String, ByVal __score As Integer, _
ByVal __reussite As Double, ByVal __duree_jeu as TimeSpan)
_pseudo = __pseudo
_score = __score
_reussite = __reussite
_duree_jeu = __duree_jeu
End Sub
end structure
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 5 janv. 2007 à 22:45
Je crois qu'on parle pas tout a fait de la meme chose. Mon excemple prend en compte des données binaires qui peuvent etre de tout type (float,double,long,byte, chaine fixe etc...) ça n'est pas tout a fait pareil que la serialisation de donnée sql ou xml. Et puis le code est bcp plus long... enfin je vais voir quand meme ce que ça donne sur un exemple concret.
@+
_Fabien
Messages postés119Date d'inscriptionvendredi 17 novembre 2006StatutMembreDernière intervention28 avril 2008 5 janv. 2007 à 15:35
C'est que m'a proposé une programmeuse avertie, mais ça ne marche pas (enfin j'y arrive pas). Jette plus tôt un coup d'oeil sur ce post du forum :
' Create a hashtable of values that will eventually be serialized.
Dim addresses As New Hashtable
addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052")
addresses.Add("Fred", "987 Pine Road, Phila., PA 19116")
addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301")
' To serialize the hashtable (and its key/value pairs),
' you must first open a stream for writing.
' In this case, use a file stream.
Dim fs As New FileStream("DataFile.dat", FileMode.Create)
' Construct a BinaryFormatter and use it to serialize the data to the stream.
Dim formatter As New BinaryFormatter
Try
formatter.Serialize(fs, addresses)
Catch e As SerializationException
Console.WriteLine("Failed to serialize. Reason: " & e.Message)
Throw
Finally
fs.Close()
End Try
End Sub
Sub Deserialize()
' Declare the hashtable reference.
Dim addresses As Hashtable = Nothing
' Open the file containing the data that you want to deserialize.
Dim fs As New FileStream("DataFile.dat", FileMode.Open)
Try
Dim formatter As New BinaryFormatter
' Deserialize the hashtable from the file and
' assign the reference to the local variable.
addresses = DirectCast(formatter.Deserialize(fs), Hashtable)
Catch e As SerializationException
Console.WriteLine("Failed to deserialize. Reason: " & e.Message)
Throw
Finally
fs.Close()
End Try
' To prove that the table deserialized correctly,
' display the key/value pairs.
Dim de As DictionaryEntry
For Each de In addresses
Console.WriteLine("{0} lives at {1}.", de.Key, de.Value)
Next
End Sub
End Module
TeBeCo
Messages postés467Date d'inscriptionlundi 24 juin 2002StatutMembreDernière intervention 9 mars 2011 4 janv. 2007 à 17:28
Je te propose une approche plus simple : La Serialisation (et deserialisation ici présente)
.net s'occupe de formatter/deformatter ta structure au format XML ou Binary suivant ton choix il gere lui meme le flux qui accede au fichier, c'est faisable et inclus depuis le framework 1.0 pour 90% des type d'objet (sauf les Dictonray qui ne sont serialisable qu'en binary)
si ce n'est pas le cas il est possible d'implementer des interface fournit par .net tel que "IXmlSerialisable" pour "recoder/personnaliser" ou carement coder la serialization si le .net ne le prevois pas
dans ton cas tu range tes structures dans une collection generique (.net 2.0) typé sur ta structure et tu serialize la collection pour l'enregistré ou deserialize a l'ouverture du prog
je vais pas faire de cours sur la serialization car je risquerai de mal expliqué certain aspect pas encore maitrisé totalement cependant je pense que c'est pour cela que .net n'inclus pas directement l'ecriture et la lecture de structure, cela a carement été étendu a presque tte les classe de .net via la serializion
j'ai pas de source simple sous la main a offrir pour vouus montrez mais la doc MSDN 2005 en est remplie
PS : milles excuses pour ttes les fautes
loskiller62
Messages postés135Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention12 juillet 20061 6 avril 2005 à 20:48
mega désolé je me suis trompé pour la différence de taille entre la méthode StrucToByte/ByteToStruc et la méthode FilePut/FileGet. Un exemple:
La différence est donc légère. Par contre je n'ai pas fait de tests de performances pour récupérer un élément à un index.
Avec ta méthode EBArtSoft pour ecrire ça va il y a une méthode Seek (avec un BinaryWriter) mais il n'y en a pas en lecture. Il faut donc lire tout les bytes qui précèdent l'objet que l'on veut lire (je fais un bon gros readbytes). Je me demande juste si ça reste aussi performant que la méthode crosoft... . L'avenir ne me le dira pas puisque j'arrête de tester les FilePut, je préfère ta méthode.
Bisous
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 4 avril 2005 à 21:27
Oui j'y avais pensé c'est une alternative mais imagine si tu doit tout declarer a chaque fois...
c'est mon coté faineant qui prend le dessus :p
loskiller62
Messages postés135Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention12 juillet 20061 4 avril 2005 à 20:38
Ceci fonctionne (VB.NET 2005 Express):
Structure MASTRUCT
<VBFixedArray(40)> Public Param1() As Byte
<VBFixedString(40)> Public Param2 As String
Public Sub Enregistrer(ByVal Index As Integer)
Dim TrueIndex As Integer Index * 2 '2 nombre d'éléments dans la structure
Dim FF As Integer = FreeFile()
FileOpen(FF, FICHIER_INDEX, OpenMode.Random)
FilePut(FF, Param1, TrueIndex, False) 'ArrayIsDynamic = False
FilePut(FF, Param2, TrueIndex + 1, True) 'StringIsFixedLength = True
FileClose(FF)
End Sub
Public Sub Charger(ByVal Index As Integer)
Dim TrueIndex As Integer = Index * 2
Dim FF As Integer = FreeFile()
FileOpen(FF, FICHIER_INDEX, OpenMode.Random)
FileGet(FF, Param1, TrueIndex, False) 'ArrayIsDynamic = False
FilePut(FF, Param2, TrueIndex + 1, True) 'StringIsFixedLength = True
FileClose(FF)
End Sub
End Structure
'Test:
Dim s As New MASTRUCT
Dim tb() As Byte = {1, 2, 3, 4}
s.Param1 = tb
s.Param2 = "coucou"
s.Enregistrer(1)
s.Charger(1)
N'est ce pas cela que tu veux faire ? Ici malheureusement c'est la méthode d'enregistrement attribut par attrribut.
Ca reste moins intéressant que la méthode que tu proposes car ça prend pas mal de place (262 octets pour l'enregistrement de la structure et au final ça reste aussi complexe que ta méthode (pourvu qu'on la connaisse bien sûr).
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 4 avril 2005 à 18:44
Non vous n'avez pas vraiment cerné le probleme !
le probleme est que dans vb.net il est "impossible" de lire des tableaux d'octets dans une structure ou bien de lire une chaine de caractere fixe (en vb6 ça donnais) :
Type MASTRUCT
Param1(40) as byte
Param2 as string *40
End Type
Avec ça meme un ReadFile ne marchera pas d'ou l'idée ci dessus.
Alors effectivement pour une structure simple et des type numerique rien n'empeche de lire avec readfile.
Le but est de lire et d'ecrire exactement ce que l'on veux sans manipulation de donnée non controlé. L'autre probleme est que les structure .net ne sont pas compatible avec les structure win32 lors de chaine ou tableau a taille fixe (a cause de l'organisation meme des données en memoire). D'ou l'impossibilité d'utiliser l'API win32.
Si vous trouvez une meilleur solution je suis prenneur a 100% :)
loskiller62
Messages postés135Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention12 juillet 20061 4 avril 2005 à 11:43
non non c'est des chiffres arrondis vite fait (pour 780 et 90), des ordres de grandeur.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 4 avril 2005 à 09:02
90 n'est ni un multiple de 4 ni de 8 donc ne devrait pas y avoir une telle structure, .net doit certainement aligner les données sur 8.
loskiller62
Messages postés135Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention12 juillet 20061 4 avril 2005 à 00:28
Bon ça marche mais ce n'est pas parfait:
* On peut enregistrer des structures avec string variables
* On peut enregistrer des strings de taille fixe
* On ne peut pas enregistrer des structures avec strings fixes
Après ça ne répond pas à mes besoins en terme de place ou de possibilités d'écrasement d'enregistrements par un autre:
* Ma structure avec des strings fixes + méthode EBartSoft: 25 octets par enregistrement + possibilité d'ecrasement
* Meme structure enregistrée attributs par attributs: 780 octets (trop gros) + possibilité d'ecrasement
* Ma structure mais avec strings variables: 90 octets + impossible d'écraser un enregistrement avec un autre car les tailles sont différentes (on ne peut pas faire passer un éléphant dans un trou de souris)
Voilà voilà. Si vous vous rendez compte d'une betise là dedans n'hésitez pas
loskiller62
Messages postés135Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention12 juillet 20061 3 avril 2005 à 23:40
Oyea oyez mes amis, pretez moi l'oreille.
Je ne penses pas me tromper en disant qu'en fait vb.net gère ça en réalité!
il faut utiliser FilePut et FileGet en lieu et place des Put et Get de vb6.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 3 avril 2005 à 23:14
Utiliser directement API ReadFile() ne serait pas gagnant en quantité de code ? en efficacité assurément et en plus permettrait de lire nimporte quoi nimporte comment.
Qu'en dis-tu ?
cs_EBArtSoft
Messages postés4525Date d'inscriptiondimanche 29 septembre 2002StatutModérateurDernière intervention22 avril 20199 3 avril 2005 à 22:58
Je dirais meme que sur ce point la c'est carrement naze...
C'est quand meme le b-a-ba de lire des structure.
esperons que ce soit corriger sur le 2.0
loskiller62
Messages postés135Date d'inscriptionjeudi 30 janvier 2003StatutMembreDernière intervention12 juillet 20061 3 avril 2005 à 20:27
Je t'ai déjà dit que je t'aimais EBArtSoft? Je crois oui...
En tout cas merci c'est nikel.
.NET me semble encore bien peu complet du point de vue des fichiers binaires...
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 1 sept. 2004 à 13:34
...le fou (°_°)
Xya
Messages postés103Date d'inscriptionlundi 8 juillet 2002StatutMembreDernière intervention24 novembre 2005 1 sept. 2004 à 13:32
(Désolé pour l'indentation le site a pas l'air d'apprécier les tabs)
Xya
Messages postés103Date d'inscriptionlundi 8 juillet 2002StatutMembreDernière intervention24 novembre 2005 1 sept. 2004 à 13:31
Je pense que le plus simple pour charger et écrire des structures dans des flux sans passer par PtrToStructure et tout le bazar Interop c'est d'écrire tout bêtement une méthode Read et Write pour chaque structure (même si on doit écrire beaucoup plus de code):
Imports System.IO
Private Structure TYPETEST
'longueur = 8
Dim Test1 As String
Public Shared Function Read(s As Stream) As TYPETEST
Dim br as BinaryReader
Dim struct As New TYPETEST
if s Is Nothing Then
Throw New ArgumentNullException("s")
Else
br = New BinaryReader(s)
End If
'on vérifie qu'il y a assez à lire
If (s.Length - s.Position) >= 16 Then
struct.Test1 = New String(br.ReadChars(8))
Else
'Erreur...
End If
Return struct
End Function
Public Sub WriteTo(s As Stream)
if s Is Nothing Then
Throw New ArgumentNullException("s")
Else
WriteFixedString(Test1, 8, New BinaryWriter(s))
End If
End Sub
Private Shared Sub WriteFixedString(text As String, size As Integer, bw As BinaryWriter)
If text Is Nothing Then
bw.Write(new String(ControlChars.NullChar, size))
Else If text.Length > size Then
bw.Write(text.Substring(0, size))
Else If text.Length < size Then
bw.Write(text.PadRight(size, ControlChars.NullChar))
Else
bw.Write(text)
End If
End Sub
End Structure
Private Sub OnWrite()
Dim vTest As New TYPETEST
Dim fs As FileStream = Nothing
Try
fs = new FileStream("Test.txt", FileMode.OpenOrCreate)
vTest.Test1 = "Manu"
VTest.WriteTo(fs)
Finally
If Not fs Is Nothing Then
fs.Close()
End If
End Try
End Sub
Private Sub OnRead()
Dim vTest As TYPETEST
Dim vData() As Byte
Dim fs As FileStream = Nothing
Try
fs = new FileStream("Test.txt", FileMode.Open)
VTest = TYPETEST.Read(fs)
Finally
If Not fs Is Nothing Then
fs.Close()
End If
End Try
End Sub
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 1 sept. 2004 à 10:26
hiiii, ben super ton code, je le cherchais aussi pour une transcription d'un programme... nikel, en fait j'avais pas pensé au tableau d'octets... mais à vrai dire je vois rien d'autre. Merci pour l'info
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 31 août 2004 à 21:21
Ca y est, tu as trouvé pour les chaines a taille fixe.
ca a l'air assez tordu.... étrange que ca existe pas en .Net (defacon plus..... directe)
Afyn, EB a pas dit qu'il quittait le VB6 !
Afyn
Messages postés608Date d'inscriptionsamedi 3 août 2002StatutMembreDernière intervention22 décembre 2016 31 août 2004 à 20:17
Ca y est ? t'as plongé ?
VB6 perd son meilleur animateur ... sniff !
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 ?
10 janv. 2007 à 12:43
@+
10 janv. 2007 à 12:14
Je suis en train d'examiner et de comprendre ton code. Je suis débutant. J'ai un certain nombre de questions à te poser :
- ligne 10 : à quoi sert le "ByVal e" et pourquoi tu ne lui as pas attribué un type ?
- Sinon, je m'attendais à voir dans le fichier "Test.txt", un truc illisible du genre "!%dff" (comme en C quand on écrit en binaire), mais c'est du texte ("Manu"). Signifie-t'il que ce n'est pas en binaire que tu écris dans ton fichier "Test.txt" ?
10 janv. 2007 à 11:41
http://www.vbfrance.com/code.aspx?ID=34964
N'empêche que c'est vraiment tordu d'écrire une struture dans un fichier binaire en VB.Net.
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 ?
8 janv. 2007 à 19:24
Yop
Afyn - Navedac
7 janv. 2007 à 13:20
Premierement : Ce n'est par ce que je ne presente que des sources en vb6 que je ne connais pas le .net
Deuxiement : As-tu deja observé un fichier généré par la methode BinaryFormatter.Serialize ?
Biensur que tu peux sauvegarder ton objet mais la on parle de structure dont l'odre des données binaire est bien definis ! Hors quand tu utilises la serialisation tu enregistres en plus des données les informations necessaire a la recuperation de ces dites données. Par consequent tu n'enregistres pas au format voulue. Relis les commentaires plus haut et tu comprendra de quelle type de données on parle.
Aller un petit exemple imaginons que je veux faire un lecteur de fichier TAR en .NET. Mon but lire les entrés de l'archive une par une. En vb6 ou en C je crée une structure que je lit en une seule ligne de code elle ressemble a ceci :
Public Type TARHEADER
Name As String * NAMSIZ
Mode As String * 8
Uid As String * 8
Gid As String * 8
Size As String * 12
mtime As String * 12
ChkSum As String * 8
Linkflag As String * 1
Linkname As String * NAMSIZ
Magic As String * 8
Reserved(246) As Byte
End Type
Maintenant comment faire en .NET ? Voila c'est pas compliqué. Par contre même en definissant un objet aux proprietés identiques je ne peux pas deserialiser directement dans l'archive TAR. Que me proposes tu ?
@+
6 janv. 2007 à 21:36
6 janv. 2007 à 21:35
La serialization se fait soit au format XML soit Binaire
Ca se fait avec TRES PEU de ligne de code et tu peux serializé 90% des objet .net sans difficulté ni code a rajouté les 10% restant reste serializable mais ya un poil de code en plus a faire et pour tout les type dont t'as parlé plus haut je vois 0 difficulté ca doit passer en 5 ligne pour appeler le serializer (avec de la marge) et peut etre 8 a la recup
ca reste qu'une question de faire de motivation et faire l'effort une fois passer a .net d'utilisé des outils adapté et non pas ce qu'on a l'habitude de faire
6 janv. 2007 à 11:49
J'abuse. Je n'ai toujours pas essayé avec ta méthode, mais bientôt :)
Public Structure HighScore
' attributs
Private _pseudo As String
Private _score As Integer
Private _reussite As Double
Private _duree_jeu As TimeSpan
' propriétés
Public Property pseudo() As String
Get
Return _pseudo
End Get
Set(ByVal value As String)
_pseudo = value
End Set
End Property
Public Property score() As Integer
Get
Return _score
End Get
Set(ByVal value As Integer)
_score = value
End Set
End Property
Public Property reussite() As Double
Get
Return _reussite
End Get
Set(ByVal value As Double)
_reussite = value
End Set
End Property
Public Property duree_jeu() As TimeSpan
Get
Return _duree_jeu
End Get
Set(ByVal value As TimeSpan)
_duree_jeu = value
End Set
End Property
' Constructeur
Public Sub New(ByVal __pseudo As String, ByVal __score As Integer, _
ByVal __reussite As Double, ByVal __duree_jeu as TimeSpan)
_pseudo = __pseudo
_score = __score
_reussite = __reussite
_duree_jeu = __duree_jeu
End Sub
end structure
5 janv. 2007 à 22:45
@+
5 janv. 2007 à 15:35
http://www.vbfrance.com/infomsg_LIRE-ECRIRE-STRUCTURE-DANS-FICHIER_865075.aspx#6
Pas encore essayé la méthode de EBArtSoft.
Vocici un exemple trouvé dans le kit SDK Frameworks 2 :
Imports System.IO
Imports System.Collections
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization
Module App
Sub Main()
Serialize()
Deserialize()
End Sub
Sub Serialize()
' Create a hashtable of values that will eventually be serialized.
Dim addresses As New Hashtable
addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052")
addresses.Add("Fred", "987 Pine Road, Phila., PA 19116")
addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301")
' To serialize the hashtable (and its key/value pairs),
' you must first open a stream for writing.
' In this case, use a file stream.
Dim fs As New FileStream("DataFile.dat", FileMode.Create)
' Construct a BinaryFormatter and use it to serialize the data to the stream.
Dim formatter As New BinaryFormatter
Try
formatter.Serialize(fs, addresses)
Catch e As SerializationException
Console.WriteLine("Failed to serialize. Reason: " & e.Message)
Throw
Finally
fs.Close()
End Try
End Sub
Sub Deserialize()
' Declare the hashtable reference.
Dim addresses As Hashtable = Nothing
' Open the file containing the data that you want to deserialize.
Dim fs As New FileStream("DataFile.dat", FileMode.Open)
Try
Dim formatter As New BinaryFormatter
' Deserialize the hashtable from the file and
' assign the reference to the local variable.
addresses = DirectCast(formatter.Deserialize(fs), Hashtable)
Catch e As SerializationException
Console.WriteLine("Failed to deserialize. Reason: " & e.Message)
Throw
Finally
fs.Close()
End Try
' To prove that the table deserialized correctly,
' display the key/value pairs.
Dim de As DictionaryEntry
For Each de In addresses
Console.WriteLine("{0} lives at {1}.", de.Key, de.Value)
Next
End Sub
End Module
4 janv. 2007 à 17:28
.net s'occupe de formatter/deformatter ta structure au format XML ou Binary suivant ton choix il gere lui meme le flux qui accede au fichier, c'est faisable et inclus depuis le framework 1.0 pour 90% des type d'objet (sauf les Dictonray qui ne sont serialisable qu'en binary)
si ce n'est pas le cas il est possible d'implementer des interface fournit par .net tel que "IXmlSerialisable" pour "recoder/personnaliser" ou carement coder la serialization si le .net ne le prevois pas
dans ton cas tu range tes structures dans une collection generique (.net 2.0) typé sur ta structure et tu serialize la collection pour l'enregistré ou deserialize a l'ouverture du prog
je vais pas faire de cours sur la serialization car je risquerai de mal expliqué certain aspect pas encore maitrisé totalement cependant je pense que c'est pour cela que .net n'inclus pas directement l'ecriture et la lecture de structure, cela a carement été étendu a presque tte les classe de .net via la serializion
j'ai pas de source simple sous la main a offrir pour vouus montrez mais la doc MSDN 2005 en est remplie
PS : milles excuses pour ttes les fautes
6 avril 2005 à 20:48
StrucToByte/ByteToStruc: 473 octets
FilePut/FileGet: 520 octets
La différence est donc légère. Par contre je n'ai pas fait de tests de performances pour récupérer un élément à un index.
Avec ta méthode EBArtSoft pour ecrire ça va il y a une méthode Seek (avec un BinaryWriter) mais il n'y en a pas en lecture. Il faut donc lire tout les bytes qui précèdent l'objet que l'on veut lire (je fais un bon gros readbytes). Je me demande juste si ça reste aussi performant que la méthode crosoft... . L'avenir ne me le dira pas puisque j'arrête de tester les FilePut, je préfère ta méthode.
Bisous
4 avril 2005 à 21:27
c'est mon coté faineant qui prend le dessus :p
4 avril 2005 à 20:38
Structure MASTRUCT
<VBFixedArray(40)> Public Param1() As Byte
<VBFixedString(40)> Public Param2 As String
Public Sub Enregistrer(ByVal Index As Integer)
Dim TrueIndex As Integer Index * 2 '2 nombre d'éléments dans la structure
Dim FF As Integer = FreeFile()
FileOpen(FF, FICHIER_INDEX, OpenMode.Random)
FilePut(FF, Param1, TrueIndex, False) 'ArrayIsDynamic = False
FilePut(FF, Param2, TrueIndex + 1, True) 'StringIsFixedLength = True
FileClose(FF)
End Sub
Public Sub Charger(ByVal Index As Integer)
Dim TrueIndex As Integer = Index * 2
Dim FF As Integer = FreeFile()
FileOpen(FF, FICHIER_INDEX, OpenMode.Random)
FileGet(FF, Param1, TrueIndex, False) 'ArrayIsDynamic = False
FilePut(FF, Param2, TrueIndex + 1, True) 'StringIsFixedLength = True
FileClose(FF)
End Sub
End Structure
'Test:
Dim s As New MASTRUCT
Dim tb() As Byte = {1, 2, 3, 4}
s.Param1 = tb
s.Param2 = "coucou"
s.Enregistrer(1)
s.Charger(1)
N'est ce pas cela que tu veux faire ? Ici malheureusement c'est la méthode d'enregistrement attribut par attrribut.
Ca reste moins intéressant que la méthode que tu proposes car ça prend pas mal de place (262 octets pour l'enregistrement de la structure et au final ça reste aussi complexe que ta méthode (pourvu qu'on la connaisse bien sûr).
4 avril 2005 à 18:44
le probleme est que dans vb.net il est "impossible" de lire des tableaux d'octets dans une structure ou bien de lire une chaine de caractere fixe (en vb6 ça donnais) :
Type MASTRUCT
Param1(40) as byte
Param2 as string *40
End Type
Avec ça meme un ReadFile ne marchera pas d'ou l'idée ci dessus.
Alors effectivement pour une structure simple et des type numerique rien n'empeche de lire avec readfile.
Le but est de lire et d'ecrire exactement ce que l'on veux sans manipulation de donnée non controlé. L'autre probleme est que les structure .net ne sont pas compatible avec les structure win32 lors de chaine ou tableau a taille fixe (a cause de l'organisation meme des données en memoire). D'ou l'impossibilité d'utiliser l'API win32.
Si vous trouvez une meilleur solution je suis prenneur a 100% :)
4 avril 2005 à 11:43
4 avril 2005 à 09:02
4 avril 2005 à 00:28
* On peut enregistrer des structures avec string variables
* On peut enregistrer des strings de taille fixe
* On ne peut pas enregistrer des structures avec strings fixes
Après ça ne répond pas à mes besoins en terme de place ou de possibilités d'écrasement d'enregistrements par un autre:
* Ma structure avec des strings fixes + méthode EBartSoft: 25 octets par enregistrement + possibilité d'ecrasement
* Meme structure enregistrée attributs par attributs: 780 octets (trop gros) + possibilité d'ecrasement
* Ma structure mais avec strings variables: 90 octets + impossible d'écraser un enregistrement avec un autre car les tailles sont différentes (on ne peut pas faire passer un éléphant dans un trou de souris)
Voilà voilà. Si vous vous rendez compte d'une betise là dedans n'hésitez pas
3 avril 2005 à 23:40
Je ne penses pas me tromper en disant qu'en fait vb.net gère ça en réalité!
il faut utiliser FilePut et FileGet en lieu et place des Put et Get de vb6.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vastmPut.asp
Je vais tester cette animalerie là tout de suite
3 avril 2005 à 23:14
Qu'en dis-tu ?
3 avril 2005 à 22:58
C'est quand meme le b-a-ba de lire des structure.
esperons que ce soit corriger sur le 2.0
3 avril 2005 à 20:27
En tout cas merci c'est nikel.
.NET me semble encore bien peu complet du point de vue des fichiers binaires...
1 sept. 2004 à 13:34
1 sept. 2004 à 13:32
1 sept. 2004 à 13:31
Imports System.IO
Private Structure TYPETEST
'longueur = 8
Dim Test1 As String
Public Shared Function Read(s As Stream) As TYPETEST
Dim br as BinaryReader
Dim struct As New TYPETEST
if s Is Nothing Then
Throw New ArgumentNullException("s")
Else
br = New BinaryReader(s)
End If
'on vérifie qu'il y a assez à lire
If (s.Length - s.Position) >= 16 Then
struct.Test1 = New String(br.ReadChars(8))
Else
'Erreur...
End If
Return struct
End Function
Public Sub WriteTo(s As Stream)
if s Is Nothing Then
Throw New ArgumentNullException("s")
Else
WriteFixedString(Test1, 8, New BinaryWriter(s))
End If
End Sub
Private Shared Sub WriteFixedString(text As String, size As Integer, bw As BinaryWriter)
If text Is Nothing Then
bw.Write(new String(ControlChars.NullChar, size))
Else If text.Length > size Then
bw.Write(text.Substring(0, size))
Else If text.Length < size Then
bw.Write(text.PadRight(size, ControlChars.NullChar))
Else
bw.Write(text)
End If
End Sub
End Structure
Private Sub OnWrite()
Dim vTest As New TYPETEST
Dim fs As FileStream = Nothing
Try
fs = new FileStream("Test.txt", FileMode.OpenOrCreate)
vTest.Test1 = "Manu"
VTest.WriteTo(fs)
Finally
If Not fs Is Nothing Then
fs.Close()
End If
End Try
End Sub
Private Sub OnRead()
Dim vTest As TYPETEST
Dim vData() As Byte
Dim fs As FileStream = Nothing
Try
fs = new FileStream("Test.txt", FileMode.Open)
VTest = TYPETEST.Read(fs)
Finally
If Not fs Is Nothing Then
fs.Close()
End If
End Try
End Sub
1 sept. 2004 à 10:26
31 août 2004 à 21:21
ca a l'air assez tordu.... étrange que ca existe pas en .Net (defacon plus..... directe)
Afyn, EB a pas dit qu'il quittait le VB6 !
31 août 2004 à 20:17
VB6 perd son meilleur animateur ... sniff !
Pas yop !
Afyn
Navedac