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 :

BufferedInputStream.read(byte) très long


Sujet :

Java

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    281
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 281
    Par défaut BufferedInputStream.read(byte) très long
    Bonjour, je récupère un string avec un code de ce genre mais sur ma freebox (protocole upnp qui utilise http).
    Mais le problème est que le dernier appelle de bis.read est très long. (2secondes)

    Quelqu'un sait y remédier ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    HttpURLConnection conn = (HttpURLConnection) new URL(
                    "http://www.free.fr/").openConnection();
            conn.connect();
     
            BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
     
            byte[] bytes = new byte[1024];
            int tmp ;
            while( (tmp = bis.read(bytes) ) != -1 ) {
                String chaine = new String(bytes,0,tmp);
                System.out.print(chaine);
            }
     
            conn.disconnect();
    Pour éviter ce genre de longue attente, j'ai remplacé la boucle paar ce code. bien sur ce n'ai pas très propre et j'aimerai avoir quelque chose de propre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    byte[] bytes = new byte[1024];
    do{
      int tmp=in.read(bytes);
      String chaine=new String(bytes,0,tmp));
      System.out.println(chaine);
      if (in.available()<=0){
        try{
          Thread.sleep(100);
        }catch(Exception e){
          e.printStackTrace();
        }
      }
    }while(in.available()>0);

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Déjà, ceci n'est pas bon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new String(bytes,0,tmp)
    Tu crée un String en utilisant l'encodage par défaut de ta plateforme et en utilisant un tableau de bytes potentiellement incomplet. Tu pourrais avoir des problèmes avec des encodage multibyte comme utf-8 si tu as recu le premier byte d'une série de 3 par exemple mais pas encore les 2 autres.

    Ensuite, bloquer sur le read ou faire un Thread.sleep parce qu'il n'y a pas de données, ça reviens strictement au même, tu bloque. Je ne vois pas ce que tu espère y gagner. Si le dernier appel à read est aussi lent, c'est probablement parce que ton serveur ne ferme pas correctement la connection ou, tout simplement, parce qu'il est lent à terminer sa réponse.

    Pour ton problème de String, utilise un Reader plutôt qu'un inputstream, tout y est déjà géré correctement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Reader reader = new InputstreamReader(conn.getInputStream(),"UTF-8");
     char[] chars = new char[1024];
            int tmp ;
            while( (tmp = bis.read(chars) ) != -1 ) {
                String chaine = new String(chars,0,tmp);
                System.out.print(chaine);
            }
    Pour ta connection, tu peux essayer de faire un conn.getOutputStream().close();, mais je doute que cela aie un effet. Si le bloquage t'ennuie, tu peux effectivement utiliser les méthodes ready()/available() suivant la classe utilisée, mais encore faut-il faire quelque chose de ce temps disponible. Comme je l'ai dit, l'utiliser pour faire un Thread.sleep est totalement inutile

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    281
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 281
    Par défaut
    Je vais suivre tes conseils pour le String.

    Pour le sleep, je l'ai fait parce que j'ai remarqué que ma réponse n'était pas complète lorsque available() renvoyait la valeur 0. et en attendant un peu, le serveur me renvoyait encore des données.
    D'après ce que je comprend donc, c'est un problème côté serveur ?

    Une autre question, si le serveur me renvoie autre chose qu'un String, comment faire ?

  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
    Salut,

    Citation Envoyé par druzy Voir le message
    Pour le sleep, je l'ai fait parce que j'ai remarqué que ma réponse n'était pas complète lorsque available() renvoyait la valeur 0. et en attendant un peu, le serveur me renvoyait encore des données.
    C'est normal : available() indique seulement la quantité de donnée disponible sans blocage lors du read().
    Bref cela permet juste de savoir si des données sont arrivées ou pas...

    Perso j'ai jamais vu un cas d'utilisation pertinent d'available().
    Je te déconseille de l'utiliser.

    Citation Envoyé par druzy Voir le message
    D'après ce que je comprend donc, c'est un problème côté serveur ?
    As-tu tester avec un navigateur ou un outil comme curl, pour voir si c'est la même chose...

    Citation Envoyé par druzy Voir le message
    Une autre question, si le serveur me renvoie autre chose qu'un String, comment faire ?
    Ben tu lis l'InputStream... et tu en fait ce que tu veux.

    C'est quoi le problème précisément ?




    Sinon il faut fermer proprement les ressources, avec le try-with-resource de Java 7 ou des try/finally !!!


    a++

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    281
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 281
    Par défaut
    Mes ressources sont correctement fermées.

    J'ai fait un test avec des pages internets et j'ai toujours le même souci. Le dernier read prend un temps considérable. Avec un navigateur, aucun souci. Mais où est le problème ?

  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 druzy Voir le message
    Mes ressources sont correctement fermées.
    Non, puisque tu n'utilises ni try-with-resource ni try/finally...

    Citation Envoyé par druzy Voir le message
    J'ai fait un test avec des pages internets et j'ai toujours le même souci. Le dernier read prend un temps considérable. Avec un navigateur, aucun souci. Mais où est le problème ?
    Quel genre de connexion utilises-tu ? As-tu un proxy ou quelque chose du genre.
    Et avec quelle version de Java ?

    Parce qu'avec le tout premier code que tu donnes (sur www.free.fr) je ne rencontre pas ce soucis.

    a++

  7. #7
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    J'ai testé ton premier programme (dans ton premier post) et l'arrêt en fin de récupération de la page est immédiat. Je ne constate aucune attente.

    EDIT : trop lent
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par druzy Voir le message
    Avec un navigateur, aucun souci.
    Le navigateur n'est pas une référence, car même si la connexion n'est pas terminée, il faut sont affichage dès qu'il a suffisamment de données. Il faut essayer avec des outils comme curl, wget, voir telnet

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    281
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 281
    Par défaut
    Pour ce qui est de mes ressources, je les ferme correctement, je ne l'ai juste pas écrit dans mon bout de code.

    J'ai "réglé" le problème en lisant le content-length des headers et en m'arrêtant au bout de ce nombre de byte.

    Mais bon c'est pas vraiment ce que j'appelle une résolution. On va dire que c'est temporaire.

    Pour répondre aux questions :
    ma version de java : java version "1.7.0_55"
    OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1)
    OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)

    essai avec wget : aucun souci.

  10. #10
    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
    Du coup quel est le bout de code exact que tu utilises ? Sur quelle adresse ?
    Parce que personne ne reproduit le problème, donc sans les infos exactes ca va être dur à trouver...

    a++

Discussions similaires

  1. BufferedInputStream read ou read(byte[])
    Par gl0be dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 30/04/2008, 07h59
  2. Demarage des programmes très long
    Par venegan dans le forum Autres Logiciels
    Réponses: 7
    Dernier message: 02/03/2006, 16h50
  3. Démarrage de windows vraiment très long
    Par krfa1 dans le forum Windows XP
    Réponses: 16
    Dernier message: 23/10/2005, 12h37
  4. delete très long
    Par slefevre01 dans le forum Oracle
    Réponses: 7
    Dernier message: 06/10/2005, 13h16
  5. Très long texte dans Quick Report - Comment faire ?
    Par delphi+ dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/08/2005, 22h18

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