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:
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:
Pattern p = Pattern.compile(word);
word ==> expression à rechercher, par exemple "A*E".
Code:
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:
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:
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:
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:
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+