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

Java Discussion :

Utilisation d'expressions régulières avec implémentation d'un CharSequence


Sujet :

Java

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Par défaut Utilisation d'expressions régulières avec implémentation d'un CharSequence
    Bonjour à tous,

    je développe une application qui fonctionnera sous Android (téléphone) et sur PC. Pour ce faire, j'écris du code java (bien sur commun aux plateformes).

    Mon but pour le moment: j'ai un fichier qui contient un très grand nombre de lignes composées comme suit :
    *Partie texte*|*Partie binaire*
    J'ai donc un séparateur | entre les deux.

    Dans la partie texte, je veux utiliser le moteur d'expressions régulière de java pour me retrouver tout un tas de pattern (sélectionner X lignes), et par la suite, exploiter la partie binaire.

    Autre but : n'avoir qu'une fois le fichier en mémoire.
    J'ai donc pensé à ce qui suit:
    Afin de facilement exploiter la partie binaire, je charge tout mon fichier dans un ByteBuffer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    byteBuffer = ByteBuffer.wrap(file.readBytes()); 
    byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
    Par contre, que donner à ma recherche textuelle via le regex ?
    Java dispose de deux classes pour les expressions régulière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Pattern p = Pattern.compile(word);
    word ==> expression à rechercher, par exemple "A*E".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Matcher m = p.matcher(XXXX);
    la fonction matcher prend en argument une chaine dans laquelle chercher. L'argument XXXX doit être un CharSequence. Généralement, cela correspond à une string. Mais moi je ne dispose que d'un ByteBuffer...
    Comme CharSequence est une interface, j'ai écrit une classe qui implémente cette interface, et contient une référence de mon ByteBuffer :

    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
     
    import java.nio.ByteBuffer;
     
    public class ByteBufferCharSequenceAccess implements CharSequence {
     
    	private ByteBuffer bb ; 
     
    	public ByteBufferCharSequenceAccess( ByteBuffer bb ){
    		this.bb = bb ;
    	}	
     
    	@Override
    	public char charAt(int arg0) {
    		return (char)bb.get(arg0);
    	}
     
    	@Override
    	public int length() {
    		return bb.capacity();
    	}
     
    	@Override
    	public CharSequence subSequence(int arg0, int arg1) {
    		String sequence = "";
     
    		for ( int i = 0 ; i < arg1 - arg0 ; i++ )
    		{
    			sequence +=	(char)bb.get(arg0 + i);
    		}
     
    		return sequence ;
    	}
     
    }
    Très bien, et donc je contruis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bbCharSeq = new ByteBufferCharSequenceAccess(byteBuffer);
    Donc bbCharSeq implémente CharSequence et contient une ref de mon fichier mi binaire / mi texte !

    Parfait, je le passe à mon regex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Matcher m = p.matcher(bbCharSeq);
    Et un petit
    me donne des résultats !!!
    Conclusion, ca fonctionne nickel !!

    Sur PC !!!
    En débug, je passe une fois dans la fonction
    - public int length()
    Puis plusieurs fois dans
    - public char charAt(int arg0)
    de mon ByteBufferCharSequenceAccess (je passe max 10 fois par exemple).

    Sur téléphone, ca ne fonctionne pas, et voilà pourquoi ce message !
    Je ne vois absolument pas à quoi ca peut etre dû, y a t il une limitation du regex sur téléphone ? Un problème d'endian ? Un problème d'encodage lors de la conversion ByteBuffer -> CharSequence ?
    Si oui, comment le régler ?

    Je trace en débug sur mon téléphone, et j'arrive à m.find(), et la ca renvoit false, bien sur je peux pas tracer dans le matcher java...
    J'ai mis des points d'arrets comme sur PC, et je m'arrete une fois dans :
    - public int length()
    Et je ne m'arrete JAMAIS dans :
    - public char charAt(int arg0)
    Contrairement à sur PC.
    Par ailleurs, dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public int length() {
    		return bb.capacity();
    	}
    le bb.capacity renvoyé est le meme sur PC que sur téléphone.

    Je penche pour un problème d'encodage mais je vois vraiment pas.

    Pourriez-vous m'aider svp ?

    Merci pour votre aide.
    A+

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 577
    Par défaut
    De ce que je peux voir dans le code du SDK Android, la première chose qu'un Matcher fait de son CharSequence, c'est d'en faire une String.

    Il commence par vérifier sa taille avec length(), d'où l'appel, puis en fait une String avec toString(). Or tu n'as pas implémenté toString() donc c'est Object.toString() qui est appelée, qui doit produire un truc genre "ByteBufferCharSequenceAccess@56475", qui ne fait absolument pas la taille annoncée par length(), et qui génère donc une exception.

    Autant dire, donc, qu'il a une gestion limitée des CharSequence puisqu'il ne les gère que juste assez pour en faire des String.

    J'ai peur que tu doive envisager de stocker, d'une part ce qui est texte dans des String, d'autre part ce qui n'en est pas dans un ByteBuffer.
    Ça occupera plus de place mais ce sera plus facile à gérer.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Par défaut
    Merci thelvin pour ta réponse qui m'aide bcp.

    Donc, si je rajoute une fonction toString de la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    	public String toString() {
    		return bb.asCharBuffer().toString();
    	}
    Ca pourrait fonctionner ? A ceci pret que ca me fait une recopie de mon buffer donc ca prend beaucoup plus de place en RAM...

    Je viens d'essayer sur PC et je ne passe jamais dans le toString implementé, et je ne peux pas actuellement essayer sur Android, mais d'apres ce que tu dis cette fonction devrait etre appelée.

    Merci.
    A+

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 577
    Par défaut
    Citation Envoyé par Muetdhiver Voir le message
    Ca pourrait fonctionner ?
    Non. asCharBuffer() ne fait pas ce que tu crois. Il permet de prendre un ByteBuffer (buffer de données type byte, 8-bit) et de le voir comme si c'était un CharBuffer (buffer de données type char, 16-bit.) Autrement dit, ton CharBuffer contiendrait moitié moins de données que ton ByteBuffer, déjà là tu vois qu'il y a une erreur de raisonnement.

    Rien n'empêcherait par contre de construire la String d'une autre façon.

    Citation Envoyé par Muetdhiver Voir le message
    A ceci pret que ca me fait une recopie de mon buffer donc ca prend beaucoup plus de place en RAM...

    Je viens d'essayer sur PC et je ne passe jamais dans le toString implementé, et je ne peux pas actuellement essayer sur Android, mais d'apres ce que tu dis cette fonction devrait etre appelée.
    Oui, oui et oui.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé
    Inscrit en
    Septembre 2002
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Septembre 2002
    Messages : 200
    Par défaut
    Merci pour ton aide, je vais donc revoir ma façon de faire.
    A+

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/10/2010, 21h00
  2. Réponses: 2
    Dernier message: 14/06/2009, 11h12
  3. Réponses: 2
    Dernier message: 26/11/2008, 09h28
  4. Utilisation d'expression régulière
    Par red210 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 16/04/2005, 16h45
  5. Réponses: 5
    Dernier message: 11/06/2002, 15h21

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