BufferedReader qui implémente Iterator

BufferedReader qui implémente Iterator - Java - Programmation

Marsh Posté le 27-11-2005 à 02:25:51    

Salut,  
 
J'ai besoin de lire un fichier texte ligne par ligne.  
Je pense utiliser un BufferedReader.  
 
Sans abstraction je ferais :  

Code :
  1. BufferedReader in = new BufferedReader(new FileReader("C:/tests/error_log" ));
  2.             String s;
  3.             while ((s = in.readLine()) != null) {
  4.                 // Traitement  
  5.             }


 
Mais j'aurais voulu ajouter un peu d'abstraction, et donc permettre aux classes utilisatrices de travailler avec un Iterator, du style :

Code :
  1. FileParser in = new FileParser(new FileReader("C:/tests/error_log" ));
  2.             String s;
  3.             Iterator it = in.iterator();
  4.             while (it.hasNext()) {
  5.                 s = (String) it.next();
  6.                 // Traitement
  7.             }


 
Je pensais créer une classe héritant de BufferedReader et implémentant Iterator, et ensuite définir les méthodes next() et hasNext().  
 
1. Est-ce une bonne idée ?
2. Pour implémenter la méthode hasNext() je pensais faire comme ça :

Code :
  1. public boolean hasNext() {
  2.         boolean hasNext;
  3.         // Marquer la position pour la lecture future
  4.         this.mark(1);
  5.         hasNext = this.read() != -1;
  6.         // Revenir à la position initiale
  7.         this.reset();
  8.         return hasNext;
  9.     }


Mais ça me parait un peu gourmand en traitement.
 
3. Comment récupérer l'objet Iterator ?  
4. Pour l'héritage, j'ai trouvé l'idée sur un autre site, je ne sais pas comment la justifier :sweat:  
 
Merci
 
 :jap:

Message cité 1 fois
Message édité par charly007 le 27-11-2005 à 02:30:51
Reply

Marsh Posté le 27-11-2005 à 02:25:51   

Reply

Marsh Posté le 27-11-2005 à 03:46:27    

charly007 a écrit :

1. Est-ce une bonne idée ?


IMO oui, c'est d'ailleurs ce que fait Python de manière standard (de plus cela permet d'utiliser n'importe quel type de donnée itérable comme source de données manipulables, très pratique pour des tests ou pour réutiliser tes fonctionalités)

Citation :

2. Pour implémenter la méthode hasNext() je pensais faire comme ça :

Code :
  1. public boolean hasNext() {
  2.         boolean hasNext;
  3.         // Marquer la position pour la lecture future
  4.         this.mark(1);
  5.         hasNext = this.read() != -1;
  6.         // Revenir à la position initiale
  7.         this.reset();
  8.         return hasNext;
  9.     }


Mais ça me parait un peu gourmand en traitement.


BufferedReader.ready() ne suffirait-il pas?

Citation :

3. Comment récupérer l'objet Iterator ?


Code :
  1. public class IterableReader extends BufferedReader implements Iterator {
  2.     /* snip */
  3.     public Iterator iterator() {
  4.         return (Iterator) this;
  5.     }
  6.     /* snip */
  7. }


Un truc du style [:spamafote]  
 
Et n'oublie pas qu'Iterator demande next(), hasNext() et remove() (qui peut ne rien faire, l'opération est optionnelle)

Citation :

4. Pour l'héritage, j'ai trouvé l'idée sur un autre site, je ne sais pas comment la justifier :sweat:


?


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 27-11-2005 à 04:07:22    

ton truc doit pas implémenter Iterator mais Iteratable.
et ne pas  hériter.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 04:07:55    

(mask, ton cast ne sert à rien)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 12:23:30    

masklinn a écrit :


BufferedReader.ready() ne suffirait-il pas?


En effet, BufferedReader.ready() suffit.
 

masklinn a écrit :


Et n'oublie pas qu'Iterator demande next(), hasNext() et remove() (qui peut ne rien faire, l'opération est optionnelle)


Oui, concernant remove() je lève UnsupportedOperationException().
 

the real moins moins a écrit :

ton truc doit pas implémenter Iterator mais Iteratable.
et ne pas  hériter.


Je dois utiliser le jdk 1.3, donc pas de Iterable.
 
Voici donc le code corrigé par vos conseils :

Code :
  1. public class IterableReader implements Iterator {
  2.     private BufferedReader br;
  3.     public IterableReader(Reader in) {
  4.         br = new BufferedReader(in);
  5.     }
  6.     public Iterator iterator() {
  7.         return this;
  8.     }
  9.     public boolean hasNext() {
  10.         boolean hasNext = false;
  11.         try {
  12.             hasNext = br.ready();
  13.         } catch (IOException e) {
  14.             // TODO Lever une exception
  15.         }
  16.         return hasNext;
  17.     }
  18.     public Object next() {
  19.         try {
  20.             return (Object) br.readLine();
  21.         } catch (IOException e) {
  22.             // TODO Lever une exception
  23.         }
  24.         return null;
  25.     }
  26.     public void remove() {
  27.         throw new UnsupportedOperationException();
  28.     }
  29. }


Code :
  1. public static void main(String[] args) {
  2.         try {
  3.             IterableReader in = new IterableReader(new FileReader("C:/tests/error_log" ));
  4.             String s;
  5.             Iterator it = in.iterator();
  6.             while (it.hasNext()) {
  7.                 s = (String) it.next();
  8.                 // Traitement
  9.                 System.out.println(s);
  10.             }
  11.         } catch (FileNotFoundException e) {
  12.             // TODO Auto-generated catch block
  13.             e.printStackTrace();
  14.         }
  15.     }


Merci :jap:

Message cité 1 fois
Message édité par charly007 le 27-11-2005 à 12:25:12
Reply

Marsh Posté le 27-11-2005 à 12:56:17    

ouais mais nan, ready ça sert pas à ça ...
 

Citation :

True if the next read() is guaranteed not to block for input, false otherwise


 
et puis ta méthode iterator() elle sert plus à grand chose ...
 
je verrais plutôt un truc comme ca :

Code :
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.util.Iterator;
  4. public class LineIterator implements Iterator {
  5. private final BufferedReader reader;
  6. private String line;
  7. public LineIterator(BufferedReader reader) {
  8.  this.reader = reader;
  9.  this.line = null;
  10. }
  11. public Object next() {
  12.  if ((this.line == null) && (! this.hasNext())) {
  13.   return null;
  14.  } else {
  15.   String toReturn = this.line;
  16.   this.line = null;
  17.   return toReturn;
  18.  }
  19. }
  20. public boolean hasNext() throws IOEWrapper {
  21.  if (this.line == null) {
  22.   try {
  23.    line = this.reader.readLine();
  24.   } catch (IOException e) {
  25.    throw new IOEWrapper(e);
  26.   }
  27.   return (line != null);
  28.  } else {
  29.   return true;
  30.  }
  31. }
  32. public void remove() {
  33.  throw new UnsupportedOperationException("LineIterator does not support remove()" );
  34. }
  35. // ---------------- IOEWrapper --------------------------
  36. public static class IOEWrapper extends RuntimeException {
  37.  private final IOException ioe;
  38.  public IOEWrapper(IOException ioe) {
  39.   this.ioe = ioe;
  40.  }
  41.  public IOException getIOException() {
  42.   return this.ioe;
  43.  }
  44. }
  45. }

Message cité 2 fois
Message édité par benou le 27-11-2005 à 12:57:29

---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 27-11-2005 à 13:46:35    

charly007 a écrit :

Je dois utiliser le jdk 1.3, donc pas de Iterable.


t'as pas obligé d'avoir l'interface pour en appliquer les principes. là, tu l'initialises quand ton iterateur ?
et puis, comment tu geres le fait que tu puisses avoir plusieurs processes qui l'appellent en meme temps ?
 
 
 
(perso, j'ai toujours cru c'était une mauvaise idée[:marc])


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 13:52:51    


en fait ça sert plus à rien ce code, quoi :/
t'as ni plus ni moins de code en utilisant directement le BufferedReader, et je vois pas l'interet :??:
 
(et sinon, coté remarques à la con: ton emploi de this est inconsistant et pollue la lecture(là c'est un avis perso), ton exception est mal nommée, et elle cache une exception qui ne devrait probablement pas l'être; si je ne m'abuse tu fais ça juste pour pouvoir te caler sur l'interface Iterator ...)
 
 
(et je persiste à dire que cet objet pourrait etre un Iterable - s'il n'y avait pas d'énormes problemes potentiels d'acces concurrent - mais *pas* un Iterator)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 14:10:20    

benou a écrit :

ouais mais nan, ready ça sert pas à ça ...
 

Citation :

True if the next read() is guaranteed not to block for input, false otherwise




J'ai vu, mais j'ai aussi vu dans InputStreamReader, pour la méthode ready() :

Citation :


An InputStreamReader is ready if its input buffer is not empty, or if bytes are available to be read from the underlying byte stream.


De plus j'ai testé et je n'ai pas eu d'exception, alors j'ai fait confiance à masklinn.

benou a écrit :


et puis ta méthode iterator() elle sert plus à grand chose ...


Pour parcourir une liste, on utilise un Iterator. Je me suis dit que ça serait bien de faire pareil [:spamafote]

Message cité 1 fois
Message édité par charly007 le 27-11-2005 à 14:13:14
Reply

Marsh Posté le 27-11-2005 à 14:10:32    

the real moins moins a écrit :

t'as pas obligé d'avoir l'interface pour en appliquer les principes.


Dans ce cas là, l'implémentation d'un itérateur n'a plus aucun intérêt en java (si on implémente pas l'interface je veux dire)

Citation :

t'as ni plus ni moins de code en utilisant directement le BufferedReader, et je vois pas l'interet :??:


Tu utilises des méthodes génériques qui bouffent de l'Iterator (ou de l'iterable, ils ont rajouté l'interface sur tous les types itérables genre ArrayList et autres?), de cette manière t'as des méthodes complètement génériques auquelle tu peux balancer des listes comme des fichiers,  la nature réelle de la donnée n'a plus d'importance [:spamafote]  
 
J0re en python quasiment tous les types de conteneurs, fichiers compris, sont itérables

Citation :

perso, j'ai toujours cru c'était une mauvaise idée


De pouvoir itérer sur un fichier [:petrus dei]

Citation :

(et sinon, coté remarques à la con: ton emploi de this est inconsistant et pollue la lecture(là c'est un avis perso), ton exception est mal nommée, et elle cache une exception qui ne devrait probablement pas l'être; si je ne m'abuse tu fais ça juste pour pouvoir te caler sur l'interface Iterator ...)


L'opération remove sur un iterator est optionnelle, donc elle doit bel et bien lancer une exteption quand elle est appelée et qu'elle ne fait rien (ou ne rien faire du tout, mais c'est risqué)

the real moins moins a écrit :

et je persiste à dire que cet objet pourrait etre un Iterable


J2SE5, et ça change pas grand chose, tu lui fais implémenter iterable et iterator (parce que créer un iterator special juste pour qu'il soit largué par le .iterator de l'Iterable c'est plus une perte de temps qu'autre chose)

Message cité 2 fois
Message édité par masklinn le 27-11-2005 à 14:14:20

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 27-11-2005 à 14:10:32   

Reply

Marsh Posté le 27-11-2005 à 14:16:51    

Je vais peut-être laisser tomber finalement  :whistle:

Reply

Marsh Posté le 27-11-2005 à 14:19:26    

masklinn a écrit :

Dans ce cas là, l'implémentation d'un itérateur n'a plus aucun intérêt en java (si on implémente pas l'interface je veux dire)

Citation :

t'as ni plus ni moins de code en utilisant directement le BufferedReader, et je vois pas l'interet :??:


Tu utilises des méthodes génériques qui bouffent de l'Iterator (ou de l'iterable, ils ont rajouté l'interface sur tous les types itérables genre ArrayList et autres?), de cette manière t'as des méthodes complètement génériques auquelle tu peux balancer des listes comme des fichiers,  la nature réelle de la donnée n'a plus d'importance [:spamafote]  
 
J0re en python quasiment tous les types de conteneurs, fichiers compris, sont itérables  


 
 
C'est bien ce que je dis, Iterable, pas Iterator.
(tu me prend pour un neuneu là ou bien?)
(et puis appliquer tes méthodes generiques qui bouffent de l'iterator - déjà, faudra m'en montrer - sur un putain de fichier, pas un conteneur, donc, c'est la porte ouverte à toutes les fenetres)

Message cité 1 fois
Message édité par the real moins moins le 27-11-2005 à 14:20:53

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 14:23:08    


mais t'arretes de me prendre pour un con ? [:mlc]
 

masklinn a écrit :

, et ça change pas grand chose, tu lui fais implémenter iterable et iterator (parce que créer un iterator special juste pour qu'il soit largué par le .iterator de l'Iterable c'est plus une perte de temps qu'autre chose)


 
si, ça change: au niveau sémantique, et par le fait qu'un crétin va pouvoir caster ton objet à la con en Iterator, et ça, ça serait pas joli-joli.
 
deuxio, non c'est pas une perte de temps: tu fais une inner classe, t'auras au pire 2 lignes en plus.

Message cité 1 fois
Message édité par the real moins moins le 27-11-2005 à 14:23:31

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 14:53:05    

the real moins moins a écrit :

en fait ça sert plus à rien ce code, quoi :/
t'as ni plus ni moins de code en utilisant directement le BufferedReader, et je vois pas l'interet :??:


à pouvoir itérer sur les lignes d'un fichier [:petrus75]
 

the real moins moins a écrit :


(et sinon, coté remarques à la con: ton emploi de this est inconsistant et pollue la lecture(là c'est un avis perso)


effectivemenet, je l'ai pas mis partout et c'est une erreur ... j'ai pas activé le warning qui va bien dans mon eclipse chez moi ...
Perso, j'aime bien l'uilisation de this. Je trouve au contraire que ça aide à la lecture. Surement une question d'habitude ...
 
 
 

the real moins moins a écrit :


, ton exception est mal nommée, et elle cache une exception qui ne devrait probablement pas l'être; si je ne m'abuse tu fais ça juste pour pouvoir te caler sur l'interface Iterator ...)


Elle ne la cache pas, elle la présente justement. Elle permet de la récupérer si tu préfères ...  
Et elle est runtime de façon à passer dans l'interface Iterator ...
 

the real moins moins a écrit :


(et je persiste à dire que cet objet pourrait etre un Iterable - s'il n'y avait pas d'énormes problemes potentiels d'acces concurrent - mais *pas* un Iterator)


Faudra que tu m'expliques comment tu gères la lecture d'un flux en accès concurent :/
Et de quels problèmes tu parles ...  
 

charly007 a écrit :

J'ai vu, mais j'ai aussi vu dans InputStreamReader, pour la méthode ready() :


Ok, mais dans ce cas tu te prends un InputStream en paramètre que tu enveloppe toi même dans un InputStreamReader ... parce que rien ne te dis que le Reader que tu te prends en paramètre du constructeur est un InputStreamReader  
 

charly007 a écrit :

Pour parcourir une liste, on utilise un Iterator. Je me suis dit que ça serait bien de faire pareil [:spamafote]


Ben oui, c'est l'objet qui est un Iterator. Ca sert à quoi de faire une méthode qui retourne this ?
A la rigueur, si tu voulais implémentaer Iterable, mais ce serait plutôt sur un autre objet, pas sur celui là ...
 

the real moins moins a écrit :

C'est bien ce que je dis, Iterable, pas Iterator.


A quel objet tu veux faire implémenter Iterable ?
 

the real moins moins a écrit :

si, ça change: au niveau sémantique, et par le fait qu'un crétin va pouvoir caster ton objet à la con en Iterator, et ça, ça serait pas joli-joli.


j'ai pas compris [:petrus75]


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 27-11-2005 à 14:56:40    

benou a écrit :

Perso, j'aime bien l'uilisation de this. Je trouve au contraire que ça aide à la lecture. Surement une question d'habitude ...

beurk.

benou a écrit :

Faudra que tu m'expliques comment tu gères la lecture d'un flux en accès concurent :/


je le gère justement pas, or, cet objet pourrait laisser croire qu'il le fait.

benou a écrit :


A quel objet tu veux faire implémenter Iterable ?


à celui dont tu a posté le code, pardi.
 

benou a écrit :


j'ai pas compris [:petrus75]


 
...


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 14:58:51    

benou a écrit :

j'ai pas compris [:petrus75]


Il considère que la classe est présentée au publique dans un module que les gens pourront utiliser et que (!!!) ils auront la possibilité de lire le fichier en castant directement le reader en Iterator [:totoz]  
(c'est à dire faire ce que je fais déjà)
(parce que là il parle de mon bouzin à moi, pas du tien)


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 27-11-2005 à 15:01:26    

(si c'est du code "privé", je vois pas, à part pour le plaisir, l'interet d'écrire 25 lignes de code qui ne sert à rien , pour boucler sur un Iterator au lieu d'un bete  
while ((line=reader.readLine())!=null) {
}
...)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 15:39:20    

the real moins moins a écrit :

à celui dont tu a posté le code, pardi.


Ca c'est l'iterateur, pas le truc iterable à partir du quel tu récupères l'iterateur ...  
 


 [:etoile_filante]


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 27-11-2005 à 15:43:14    

benou a écrit :

Ca c'est l'iterateur, pas le truc iterable à partir du quel tu récupères l'iterateur ...  


ha oui, juste.
 
enfin, je continue à trouver ça inutile :D


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 16:08:21    

the real moins moins a écrit :

enfin, je continue à trouver ça inutile :D


Bha, dans certains cas peut être ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 27-11-2005 à 16:10:43    

the real moins moins a écrit :

(si c'est du code "privé", je vois pas, à part pour le plaisir, l'interet d'écrire 25 lignes de code qui ne sert à rien , pour boucler sur un Iterator au lieu d'un bete  
while ((line=reader.readLine())!=null) {
}
...)


J'ai déjà parlé de pouvoir envoyer n'importe quel conteneur itérable à des méthodes, on peut ajouter une syntaxe beaucoup plus simple en Java5 grâce au combo foreach + Iterable :o


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 27-11-2005 à 16:11:37    

benou a écrit :

Bha, dans certains cas peut être ...


 

masklinn a écrit :

J'ai déjà parlé de pouvoir envoyer n'importe quel conteneur itérable à des méthodes, on peut ajouter une syntaxe beaucoup plus simple en Java5 grâce au combo foreach + Iterable :o


 
ya ya, give me concrete use cases, et on en reparle, hein


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 16:17:12    

Tu traites des logs ligne par ligne, tu permets d'entrer soit le chemin d'un fichier de log soit de coller dans un champ texte le bout de log à analyser.
 
Tu fais une fonction de traitement qui prend un itérateur sur des lignes de log et baste [:spamafote]


Message édité par masklinn le 27-11-2005 à 16:17:32

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 27-11-2005 à 17:15:52    

euh, non, je fais un traitement sur un Reader [:marc]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 27-11-2005 à 20:10:35    

BufferedReader [:aloy]


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 27-11-2005 à 22:44:42    

ton troll est débile, mais j'vais quand même te dire une truc mon p'tit gars, depuis que j'ai eu des newlines dans certains champs d'un fichier en CSV, je relativise vachement la lecture ligne par ligne.
http://www.chanson.udenap.org/photos/g_i/gabin_jean.jpg

Reply

Marsh Posté le 28-11-2005 à 01:10:36    

benou a écrit :

BufferedReader [:aloy]


ben non


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 28-11-2005 à 10:08:04    

moi je mets +1 sur --, si le stream est déjà bufferisé, pas la peine de bufferiser le reader qui est dessus.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 28-11-2005 à 12:23:59    

(d'autant que dans l'exemple à la noix de masklinn -(give me real uses cases, morons)-, on utiliserait un BufferedReader(FileReader) ou un StringReader qu'il n'y aurait pas besoin de bufferiser :o


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 28-11-2005 à 12:24:33    

(ha oué, spour avoir readLine() qu'il veulent faire ça en fait :o)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 28-11-2005 à 16:49:14    

nraynaud a écrit :

ton troll est débile, mais j'vais quand même te dire une truc mon p'tit gars, depuis que j'ai eu des newlines dans certains champs d'un fichier en CSV, je relativise vachement la lecture ligne par ligne.
http://www.chanson.udenap.org/phot [...] n_jean.jpg


 
un truc pareil ca mérite le pal direct....le fouet à pointes à minima...


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 28-11-2005 à 22:33:28    

nraynaud a écrit :

moi je mets +1 sur --, si le stream est déjà bufferisé, pas la peine de bufferiser le reader qui est dessus.


spourça que mon constructeur prend un BufferedReader et pas un Reader sinon t'es obligé de le (ré)encapsuler par un bufferedreader pour pourvoir faire le readline.
 
donc c'est plus un -1 que tu mets sur -- ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed