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 :
Par contre, que donner à ma recherche textuelle via le regex ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 byteBuffer = ByteBuffer.wrap(file.readBytes()); byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
Java dispose de deux classes pour les expressions régulière :
word ==> expression à rechercher, par exemple "A*E".
Code : Sélectionner tout - Visualiser dans une fenêtre à part Pattern p = Pattern.compile(word);
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...
Code : Sélectionner tout - Visualiser dans une fenêtre à part Matcher m = p.matcher(XXXX);
Comme CharSequence est une interface, j'ai écrit une classe qui implémente cette interface, et contient une référence de mon ByteBuffer :
Très bien, et donc je contruis :
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 ; } }
Donc bbCharSeq implémente CharSequence et contient une ref de mon fichier mi binaire / mi texte !
Code : Sélectionner tout - Visualiser dans une fenêtre à part bbCharSeq = new ByteBufferCharSequenceAccess(byteBuffer);
Parfait, je le passe à mon regex :
Et un petit
Code : Sélectionner tout - Visualiser dans une fenêtre à part Matcher m = p.matcher(bbCharSeq);
me donne des résultats !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part m.find()
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
le bb.capacity renvoyé est le meme sur PC que sur téléphone.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public int length() { return bb.capacity(); }
Je penche pour un problème d'encodage mais je vois vraiment pas.
Pourriez-vous m'aider svp ?
Merci pour votre aide.
A+
Partager