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

Langage Java Discussion :

Bug avec un BufferedReader


Sujet :

Langage Java

  1. #1
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut Bug avec un BufferedReader
    Bon j'ai un petit soucis avec un BufferedReader...
    Je parcours un fichier avec celui-ci.
    Mon problème est qu'à la création de ce buffer, il n'est pas prêt à être lu (ready()=false) et si j'utilise le debugger en pas à pas, au pas suivant la fonction ready() renvoie "true".
    Je ne comprends pas cette erreur... Voici mon code:
    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
     
    BufferedReader ficTexte = new BufferedReader(new InputStreamReader(stream));
     
    		int count = 0;
    		try {
     
    			if (stream == null) {
    				logger.debug("[ResubFormController]>>>>> Stream null");
    				throw new FileNotFoundException("[ResubFormController]countPj>>>Fichier non trouvé:");
    			}
     
     
    			if(ficTexte.ready()){
    				do {
    					String ligneEntiere = ficTexte.readLine();
    					if (ligneEntiere != null) {
     
    						try{
     
    							ligne = ligneEntiere.split("=")[0];
    							if (ligne.equals(ligne_a_trouver)) 
    							{ 
    								String trouve = ligneEntiere.split("=")[1] ;
    								logger.debug(">>>> "+ligne_a_trouver+" : "+trouve);
    								count = count+1;
     
    							} 
     
    						}
     
     
    						catch(Exception e){
    							logger.debug("[ResubFormController]>>>> Erreur pendant la lecture du fichier, recherche du nb de pj");
    							break;
    						}
    					}
    					else
    						break;
    				} while ( ficTexte != null);
     
    				ficTexte.close();
     
    				return count;
    			}
    			else{
    				logger.debug("[ResubFormController]>>>>> Erreur de lecture du fichier...");
    				return -1;
    			}
    		}
    en gros en lecture ficTexte.ready() reste à false
    en debugger après BufferedReader ficTexte = new BufferedReader(new InputStreamReader(stream));
    ficTexte.ready() est "false" et si je vais à létape suivant avec F6, je passe à true... J'ai essayé de mettre un sleep suffisemment grand (5s) entre ses 2 etapes mais le comportement reste le même.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Quelques remarques :
    • Ton log en cas de stream null est mal placé puisqu'il ne sera jamais exécuté : si stream est null le constructeur d'InputStreamReader remonterait une NPE...
    • Il est préférable d'utiliser un try/finally pour libérer la ressource...
    • Il ne faut pas baser son code sur ready(), car il se contente d'indiquer qu'il y a des données à lire sans blocage. Toi tu veux lire le fichier dans tous les cas, donc contente-toi de le lire.



    Bref ton code devrait plutôt ressembler à cela :
    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
    		// 1. Il vaut mieux générer l'exception AVANT de créer le flux
    		if (stream == null) {
    			logger.debug("[ResubFormController]>>>>> Stream null");
    			throw new FileNotFoundException("[ResubFormController]countPj>>>Fichier non trouvé:");
    		}
     
    		// 2. On crée le flux suivi immédiatement par un try/finally pour le fermer proprement :
    		BufferedReader ficTexte = new BufferedReader(new InputStreamReader(stream));
    		try {
     
    			String ligneEntiere;
     
    			// 3. On lit le fichier tant qu'il y a des données :
    			while ( (ligneEntiere=ficTexte.readLine()) != null ) {
     
    				// Traitement sur la ligne
     
    			}
     
    		} finally {
    			ficTexte.close();
    		}

    a++

  3. #3
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    Merci beaucoup pour cette réponse.

    J'ai en effet déplacé le test sur la nullité du stream car bonne remarque, il était mal placé.
    J'avais oublié les 2 catch (1 sur IOEcxeption et 1 sur FileNotFoundException) dans le code que je vous ai fourni.

    Pour le ready je l'ai rajouté suite à ce bug... Je m'explique car c'est assez complexe.
    Je développe sur mon PC en local avec Eclipse, et je déploie pour tester et debugger sur un tomcat en local sur mon pc également.
    Si tout fonctionne (ce qui était le cas en local sans la fonction ready) je déploie sur un autre tomcat sur une machine distante ou je n'ai pas d'outil pour debugger.
    En déployant sur cette machine distante je me suis apperçu que mon code ne fonctionnait pas correctement, le fichier n'était pas lu, il y avait une IOException sur ficTexte.readLine. Pour retester en local j'ai donc rajouté ce ready, et me suis aperçu que le bug apparaissait alors aussi en local. Je ne vois pas à quoi cela peut être du...

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Pourquoi avoir rajouté le ready() ??? Et quel est l'IOException en question ?

    a++

  5. #5
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    J'ai d'abord testé le ready dans les expressions du debugger pour voir son état avant de faire le readLine, et c'est à ce moment que le bug est apparu en Local.
    Je l'ai ensuite inséré au code afin de gérer un message d'erreur à l'utilisateur.
    Pour IOException malheureusement il passe dans ce "catch" mais le message d'erreur est "null"...

    Si je retire le test sur la fonction "ready" dans le code et dans le debugger cela fonctionne correctement en locale mais toujours pas sur ma machine distante.

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lodilodi Voir le message
    Pour IOException malheureusement il passe dans ce "catch" mais le message d'erreur est "null"...
    e.printStackTrace()
    Il n'y a que cela de vrai...


    a++

    PS : Et je maintient que le ready() est complètement inutile voir même incorrect...

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Je suis d'accord avec adiguba, j'ai jamais utilisé cette méthode, readLine suffit à elle seule dans la plupart des cas

  8. #8
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    J'ai redéployer avec le e.printStackTrace() sur ma machine distance, vu que je n'ai pas de bug en local sauf justement avec le ready() qui me permet de retrouver le même bug qu'en distant... (une fois le problème résolu je le retirerais vu qu'en effet il ne me sert pas à grand chose)
    Aucune trace n'apparait entre mes 2 logger...

    Voilà ma trace:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    091214 1750:02 INFO  RemoteDocHttp.findDocumentFile - findDocumentFile: filelength=921
    091214 1750:02 DEBUG ResubFormController.countPj - [ResubFormController]>>>>> Fonction countPj
    091214 1750:02 DEBUG ResubFormController.countPj - >>> erreur fonction countpj()IOException: null
    091214 1750:02 DEBUG Compiler.generateJava - Generated /usr/local/apache-tomcat-5.5.17/work/Catalina/localhost/CI01R4//org/apache/jsp/WEB_002dINF/jsp/tiles_002dbody/resub_jsp.java total=41 generate=8 validate=33
    091214 1750:02 DEBUG JDTCompiler.generateClass - Compiled /usr/local/apache-tomcat-5.5.17/work/Catalina/localhost/CI01R4//org/apache/jsp/WEB_002dINF/jsp/tiles_002dbody/resub_jsp.java 92ms
    Alors que mon catch est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    catch (IOException e) {
    			e.printStackTrace();
    			logger.debug(">>> erreur fonction countpj()IOException: "+e.getMessage());
    			return count;
    		}
    Merci pour le temps passé à essayer de m'aider.

  9. #9
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    Bonjour,

    Je n'ai toujours pas réussis à résoudre mon problème...

    Après multiples debuggage en local, il semblerait que parfois mon InputStream soit fermé au moment de faire le read().
    L'InputStream en question est un AutoCloseInputStream.
    Je suppose qu'en distant ce "bug" se produit tout le temps puisqu'impossible de lire les fichiers pour bien accessible (la taille du fichier récupéré n'est pas nul et quan je test l'url ça m'affiche bien le fichier)
    Comment puis-je convertir cet AutoCloseInputStream pour qu'il ne se ferme pas automatiquement?

    Il est toujours instancié en InputStream jamais AutoClose n'est spécifié, peut être est-ce du à Spring?
    Toujours est-il que cela semble poser problème.

  10. #10
    Membre chevronné Avatar de Mobius
    Profil pro
    none
    Inscrit en
    Avril 2005
    Messages
    463
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : none

    Informations forums :
    Inscription : Avril 2005
    Messages : 463
    Par défaut
    Le mieux pour avancer serait d'avoir la stack de l'exception.

    e.printStackTrace() affiche la stack dans la sortie standard (la console généralement)
    Généralement les loggers sont configurés pour sortir les logs dans un fichier.

    Donc il est fort probable que ta stack et tes logs ne soient pas au même endroit.
    Commence par trouver cette stack, ca t'évitera de faire des corrections sans savoir précisément ce que tu as à corriger.

  11. #11
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    Bonsoir,

    J'ai eu d'autres exceptions et la stack s'écrivait au même endroit que mes logs...
    Mais même si ce n'ai pas le cas dans cette fonction, j'ai quand même une IOException à null...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ResubFormController.countPj - >>> erreur fonction countpj()IOException: null
    Après investigation, l'AutoCloseInputStream serait du à la fonction getResponseBodyAsStream() de la classe httpMethodBase.
    Je deviens dingue avec ce bug plus que bloquant dans mes traitements de fichiers
    Il n'y aurait pas un autre moyen de récupérer autre chose qu'un AutoCloseInputStream en récupérant un fichier via http?

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Pour récupérer un fichier en utilisant struts par exemple c'est facile, on utilise un FormFile dans le formulaire et tu récupère soit le contenu dans un byte[] ou un InputStream. Sinon il ya aussi FileUpload de apache common.

  13. #13
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    J'avance tout doucement...

    Hibour, je n'utilise pas de formulaire pour récupérer mon fichier, mais le chemin du fichier en bdd.
    J'ai changé de méthode, je n'utilise plus la classe httpMethodBase mais un bout de code utilisant URL et URLconnection.
    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
    try {
    			URL myurl = new URL(HOST);
     
    			//////// EN TEST
    			URLConnection uc = myurl.openConnection();
    			String FileType = uc.getContentType();
    			int FileLenght = uc.getContentLength();
    			if (FileLenght == -1) {
    				throw new IOException("Fichier non valide.");
    			}
    			in = uc.getInputStream();
    		} 
    		catch (MalformedURLException e) {
    			System.err.println(HOST + " : URL non comprise.");
    		} catch (IOException e) {
    			System.err.println(e);
    		} 
     
     
    		return in;
    En local toujours pas de soucis, je ne récupere plus un AutoCloseInputStream mais un InputStream "simple", mais cela ne fonctionne toujours pas à distance...
    La taille de mon fichier n'est toujours pas null aucune exception dans ma fonction qui récupère le fichier, mais mon InputStream est à null.

    Pour info, je développe sous Eclipse avec Spring et Hibernate.

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Peut être c'est un problème d' url incorrect à ton fichier distant. Regarde les constructeur de URL. ca peut etre http:// ou ca peut etre un fichier locale dans ce cas faut faire file:///ton chemin.

  15. #15
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    Non je trace l'url qu'il utilise pour récupérer le fichier et ai même testé et ça m'affiche correctement toutes les lignes du fichiers qui est un fichier texte.
    L'url utilisée est la même en local et sur mon serveur distant.
    J'ai également vérifié toutes les autorisations d'accès au fichier...
    (dans mon cas l'url est du http://)

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Si t'a testé et que ça affiche toutes les lignes alors où est le problème???

  17. #17
    Membre averti
    Inscrit en
    Mars 2007
    Messages
    26
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2007
    Messages : 26
    Par défaut
    Citation Envoyé par hibour Voir le message
    Si t'a testé et que ça affiche toutes les lignes alors où est le problème???
    oui j'affiche toute les lignes quand je mets directement l'url dans mon navigateur. Le fichier apparait dans la fenêtre du navigateur mais là n'est pas mon problème, j'ai fait cela uniquement pour voir si mon url était correcte.
    Mais quand je veux lire le fichier par java (en utilisant cette url) je ne peux pas faire le read car mon InputStream est null... et pourtant l'url est bien valide.

  18. #18
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    Le fichier que tu veux lire n'est pas dans le serveur? Si c'est le cas faudra utiliser un truc dans le genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("urlFichierLocal");

Discussions similaires

  1. Bug avec le test de profondeur
    Par Tellmarch dans le forum OpenGL
    Réponses: 1
    Dernier message: 17/10/2004, 00h59
  2. Bug avec requete
    Par arsgunner dans le forum ASP
    Réponses: 8
    Dernier message: 14/06/2004, 16h25
  3. [C#] Bug (?) avec la propriété TransparencyKey de la Form
    Par FrigoAcide dans le forum Windows Forms
    Réponses: 5
    Dernier message: 21/05/2004, 14h14
  4. [CR9] Bug avec les champs à valeur vide ?
    Par Djob dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 15/07/2003, 21h21

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