IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Initialiser une classe Java via un tableau d'octets


Sujet :

Collection et Stream Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Initialiser une classe Java via un tableau d'octets
    Bonjour,

    Je récupère via un flux de données un tableau d’octets ( en provenance d'une liaison série). J’aimerai qu’une classe JAVA fasse référence à celui-ci et vienne initialiser tous ses attributs automatiquement (non pas attributs par attributs car source d’erreur) suivant les données du tableau (130 000 octets) . Mes attributs de classe sont composé que de type primitif (byte,short,int).

    Par analogie au langage C, j’ai une structure C où l’adresse de début de celle-ci pointe vers le début du tableau.

    J’aimerai vers la même chose en JAVA malheureusement, ce langage est dépourvu de pointeur, mais peu-être qu’il existe une alternative.

    Merci d'avance pour votre aide !

  2. #2
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Points : 1 745
    Points
    1 745
    Par défaut
    Une piste : Object streams

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    En effet, j'ai déjà un peu regardé de ce coté, mais je n'ai pas trouvé de solution adéquate.

    Je m'explique je ne peux utiliser un readObject() sur mon flux, car je n'ai pas fait de writeObject() au préalable.
    Mais je me suis peut-être trompé.

    Petite précision:
    D'un coté je reçois une suite d'octet et de l'autre j'ai une feuille papier qui m'indique à quoi correspond le premier, deuxième, etc.

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Points : 7 163
    Points
    7 163
    Par défaut
    Il te "suffit" de combiner les octets pour reconstruire les int, long, float....
    Tu inverse la technique d'écriture pour la transformer en lecture.
    Il te faut les index et les tailles de chaque donnée dans le tableau d'octets. Pour chaque donnée, tu combines les octets puis tu appelles la méthode "set" adéquate sur ton objet de destination.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Biloute88 Voir le message
    Je m'explique je ne peux utiliser un readObject() sur mon flux, car je n'ai pas fait de writeObject() au préalable.
    Mais je me suis peut-être trompé.
    Non, c'est exact. La sérialisation Java, c'est uniquement de Java à Java.

    Ton problème, c'est pas qu'une histoire de pointeurs. Les types n'ont pas forcément la taille qui t'arrange, et il peut y avoir conflit big-endian/little-endian.

    La seule solution c'est ce que dit dinobogan. Et c'est vrai que ce n'est pas super facile, Java n'étant pas trop prévu pour les manipulations bas niveau sur les octets.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    ScatteringByteChannel?
    mais là il faut faire les choses champs par champs ... désolé.
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    ScatteringByteChannel?
    Là je t'avoue que je vois pas bien à quoi il sert.
    ByteBuffer et LongBuffer etc, encore, ça éviterait de se casser l'oignon, soit à compter l'index, soit à convertir les bytes en d'autres types.

    Mais ScatteringByteChannel je vois pas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Je vous remercie de vos réponses.

    Hier soir, j'ai trouvé une solution qui semble fonctionner. J'utilise la méthode getField() pour récupérer et initialiser mes attributs, je vous donne mon code.

    Pensez-vous que cette solution est viable?

    Ma classe Param_inst:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    public class Param_inst {
    // tableau de string me précisant l'ordre des attribut de la classe
     
        public static final String[] tab_nomVariable = {"nbr_utilisateur1", "nbr_utilisateur2", "nbr_utilisateur3", "nbr_utilisateur4", "nbr_utilisateur5",
            "nbr_utilisateur6", "nbr_utilisateur7", "nbr_utilisateur8", "nbr_utilisateur9"};
     
        // Attribut de la classe
        public static int nbr_utilisateur1;
        public static byte nbr_utilisateur2;
        public static short nbr_utilisateur3;
        public static byte nbr_utilisateur4;
        public static byte nbr_utilisateur5;
        public static short nbr_utilisateur6;
        public static byte nbr_utilisateur7;
        public static byte nbr_utilisateur8;
        public static byte nbr_utilisateur9;
     
        //constructeur
        public Param_inst() {
        }
     
     
        // initialise chaque attribut de ma classe avec le tableau d'octet tab_octet
        public static void initialisation(byte[] tab_octet, Param_inst o) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, IOException {
     
            // Initialisation de mon flux de lecture
            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(tab_octet));
     
            //Lecture de mon tableau de String
            for (int i = 0; i < tab_nomVariable.length; i++) {
     
                //je recupere l'attribut 
                Field field = o.getClass().getDeclaredField(tab_nomVariable[i]);
                // Variable tampon pour le type de mon attribut
                Class<?> tmp;                  
                tmp = field.getType();
     
     
                //test du type de mon attribut
                if (tmp == byte.class) {
                    //set mon attribut
                    field.setByte(o, dis.readByte());
                }
                if (tmp == short.class) {
                    //set mon attribut (reverseByte me permet de récuperer la bonne valeur car mon tableau d'octet et en litle endian
                    field.setShort(o, Short.reverseBytes(dis.readShort()));
                }
                if (tmp == int.class) {
     
                    field.setInt(o, Integer.reverseBytes(dis.readInt()));
                }
            }
        }
    }
    Main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
        public static void main(String[] args) throws Exception {
            //création de mon tableau d'octet
            byte[] tab_octet = new byte[100];
            // Simulation de ma communication serie (je travail avec un fichier pour le moment
            FileInputStream fis = new FileInputStream("flux");
            //initialisation de mon tabelau
            fis.read(tab_octet);
     
            //creation de ma classe
            Param_inst pojo = new Param_inst();
            // initialisation de ma classe
            Param_inst.initialisation(tab_octet, pojo);
     
            //affichage des valeurs
            System.out.println(Param_inst.nbr_utilisateur1);
            System.out.println(Param_inst.nbr_utilisateur2);
            System.out.println(Param_inst.nbr_utilisateur3);
            System.out.println(Param_inst.nbr_utilisateur4);
            System.out.println(Param_inst.nbr_utilisateur5);
     
        }

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Ça me semblerait plus simple de parcourir la liste des declaredFields de ta classe, plutôt que de recopier à la main tous les noms des fields.

    Mais à part ça, on peut pas vraiment faire plus simple que ça.

    Moi, je me suis fait une classe utilitaire qui étend DataInputStream pour gérer l'endianness, mais je n'en ai pas trouvé dans Java ou dans une bibliothèque courante.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Là je t'avoue que je vois pas bien à quoi il sert.
    ByteBuffer et LongBuffer etc, encore, ça éviterait de se casser l'oignon, soit à compter l'index, soit à convertir les bytes en d'autres types.

    Mais ScatteringByteChannel je vois pas.
    tu crée des buffers spécialisés chacun avec ses problèmes de données (comme petit boutien) et ensuite le ScaterringByteChannel les peuple d'un seul coup d'un seul. utilisé pour decrypter des protocoles (archaïques?) de type données.
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    D'après la Doc la méthode getDeclaredField() n'est pas forcement ordonnée or j'ai besoin de récupérer avec certitude l'ordre de déclaration des attributs pour associer les données du tableau au bon attribut.

    La méthode reverseBytes() n'est pas suffisante pour gérer l'endianness?

  12. #12
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    tu crée des buffers spécialisés chacun avec ses problèmes de données (comme petit boutien) et ensuite le ScaterringByteChannel les peuple d'un seul coup d'un seul. utilisé pour decrypter des protocoles (archaïques?) de type données.

    Marrant . Je connaissais ScaterringByteChannel en lecture, je n'avais pas réalisés que ça faisait parfaitement l'écriture.
    Cela dit, ça reste assez contraignant en pratique, pour le besoin exprimé.

    Citation Envoyé par Biloute88 Voir le message
    D'après la Doc la méthode getDeclaredField() n'est pas forcement ordonnée or j'ai besoin de récupérer avec certitude l'ordre de déclaration des attributs pour associer les données du tableau au bon attribut.
    De fait. Je n'avais pas pensé à l'ordre.

    Citation Envoyé par Biloute88 Voir le message
    La méthode reverseBytes() n'est pas suffisante pour gérer l'endianness?
    Si, mais au niveau conception objet ce n'est pas très élégant. À partir du moment où j'utilise un DataInputStream pour décoder mes types de base, il me semble qu'il devrait aussi s'occuper de décoder dans la bonne endianness, et ainsi me fournir une donnée utilisable telle quelle, sans conversion supplémentaire.

    En réalité, DataInputStream n'a pas vocation à décoder des données binaires venant d'ailleurs, DataInputStream n'a comme vocation que de lire ce qu'écrit un DataOutputStream.
    Du coup, je me suis fait ma propre classe qui gère tout cela sans s'embêter.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Je te remercie, pour les informations que tu as apportées. Je vais adapter mon code en conséquence.


    Merci à tous.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Appeler une méthode d'une classe JAVA via Javascript
    Par iliass001 dans le forum Général Java
    Réponses: 5
    Dernier message: 15/05/2013, 13h23
  2. [XSLT] Faire la transformation via une classe Java
    Par Tiffado dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 04/02/2013, 17h40
  3. Réponses: 4
    Dernier message: 30/12/2011, 12h04
  4. accéder à une classe JAVA via un Scripted Data Set
    Par elbrujo2323 dans le forum BIRT
    Réponses: 3
    Dernier message: 19/03/2008, 16h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo