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

Entrée/Sortie Java Discussion :

InputStream.available()


Sujet :

Entrée/Sortie Java

  1. #1
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut InputStream.available()
    Une petite question bête, pourquoi suis-je limité par l'InputStream. Avec cet exemple je ne lit que les 2767 premiers caractères....

    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
            URL url = null;
            InputStream stream = null;
            InputStreamReader reader = null;
            try{
                url = new URL("http://www.google.fr");
    	        stream = url.openStream();
    	        reader = new InputStreamReader(stream);
    	        char[] chars = new char[stream.available()];
    	        reader.read(chars);
    	        String s = new String(chars);
    	        System.out.println(s.length() + " caractères lus.");
    	        System.out.println(s);
            }
            catch(Exception e){
                System.out.println(e.getMessage());            
            }
            finally{
                try{reader.close();}catch(IOException e){System.out.println(e.getMessage());}
            }
    la finalité étant d'accéder à une page pour recupérer le code html et ensuite parser pour faire mon traitement....

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 7
    Par défaut
    La méthode read(byte[] array) d'un InputStream n'est pas censé garantir la lecture de l'intégralité des données. C'est pour cela qu'elle renvoie un int qui t'indique combien de byte ont été lu.

    Voici comment lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    InputStream is:
    int nbDataRead = 0;
    int nbData = is.available();
    byte[] data = new byte[nbData];
     
    while(nbDataRead < nbData)
    {
            nbDataRead += is.read(data, nbDataRead, nbData - nbDataRead);
    }

  3. #3
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    C'est en effet ce que j'avais fait au début, mais le probleme c'est qu'apres avoir le nombre de byte que me renvoie available() au premier passage, il me renvoie toujours 0.

  4. #4
    Membre éclairé Avatar de Vesperal
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Par défaut
    Essaye plutôt comme ca :

    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
    public String getTextContent() {
    		String content="No source available";
    		try {
    			InputStreamReader istr=new InputStreamReader(this.current_connection.getInputStream());
    			BufferedReader buf=new BufferedReader(istr);
    			String line;
    			content="";
    			line=buf.readLine();
    			content+=line+"\n";
     
    			while (buf.ready()) {
    				line=buf.readLine();
    				content+=line+"\n";
    			}
     
    			istr.close();
    			buf.close();
    		}
    		catch (IOException ioe) {
    			ioe.printStackTrace();
    		}
     
    		return content;
    	}
    J'avais utilisé ce code pour afficher la source d'une page web dans un navigateur perso en java.
    Ca te conviendrais ?

    p.s : this.current_connection était un objet URlConnection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	private URLConnection current_connection;
    que j'instantiais comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void connect() {
    		try {
    			this.current_connection=current_url.openConnection();
    		}catch (IOException ioe) {
    			ioe.printStackTrace();
    		}
    	}
    après avoir défini l'URL courante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void setUrl(String url) {
    		try {
    			this.current_url=new URL(url);
    		}catch(IOException ioe) {
    			ioe.printStackTrace();
    		}
    	}

  5. #5
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    Bon j'ai essayer avec un BufferedReader comme tu m'as dit mais le resultat est le même. 2767 caracteres

    j'ai utilisé un StringBuffer puisqu'on marche par ajout mais je ne pense que ca vienne de la....

    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
            URL url = null;
            InputStream stream = null;
            InputStreamReader inputReader = null;
            BufferedReader bufReader = null;
            try{
               url = new URL("http://www.google.fr");
               stream = url.openStream();
               inputReader = new InputStreamReader(stream);
               bufReader = new BufferedReader(inputReader);
               StringBuffer content = new StringBuffer(bufReader.readLine());
               while (bufReader.ready())
                   content.append(bufReader.readLine() + "\n");
               System.out.println(content.length() + " caractères lus.");
               System.out.println(content);
            }
            catch(Exception e){
                System.out.println(e.getMessage());           
            }
            finally{
                try{bufReader.close();}catch(IOException e){System.out.println(e.getMessage());}
            }

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


    Si tu ne recois que 2767 caractères cela signifie qu'il ne doit pas y en avoir plus...


    Sinon quelque remarques sur ton code :
    • Tu peux remonter la gestion des exception d'un cran, cela te permet de ne pas avoir de bloc try/catch dans le bloc finally...
    • Tu peux te passer du BufferedReader en gérant toi même un buffer. Cela t'évite de créer plusieurs String temporaire.


    Cela pourrait donner (en remontant l'exception) :
    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
    	public static String download(String urlString) throws IOException {
    		URL url = new URL(urlString);
    		InputStreamReader  inputReader = new InputStreamReader(url.openStream());
    		try{
    			StringBuffer content = new StringBuffer();
    			char[] c = new char[2048];
    			int r;
     
    			while ( (r=inputReader.read(c)) > 0 ) {
    					content.append(c,0,r);
    			}
    			//System.out.println(content.length() + " caractères lus.");
    			return content.toString();
    		}
    		finally{
    			inputReader.close();
    		}
    	}
    a++

  7. #7
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    Citation Envoyé par adiGuba
    Si tu ne recois que 2767 caractères cela signifie qu'il ne doit pas y en avoir plus...
    J'ai tester avec plusieurs page mais celle que j'ai mis est un bon exemple
    vas sur www.google.fr et affiche la source, puis execute mon code et compare... c'et surprenant.


    Citation Envoyé par adiGuba
    Sinon quelque remarques sur ton code :
    • Tu peux remonter la gestion des exception d'un cran, cela te permet de ne pas avoir de bloc try/catch dans le bloc finally...
    • Tu peux te passer du BufferedReader en gérant toi même un buffer. Cela t'évite de créer plusieurs String temporaire.
    En fait ca sera pas organiser comme ca, j'ai mis ca rapidement dans un main pour montrer le principe.
    • IoException sera effectivement remontée.
    • Je me passait du BufferedReader (cf.premier post) mais c'etait suite au post de Vesperal.
    • je ne créé pas de String temporaire puisque j'utilise un StringBuffer


    Pour la lecture, mon premier code revient au meme qu'au tiens sauf que je lit tout le reader d'un coup au lieu de lire caractere par caractere dasn une boucle. Mais j'ai essaye les deux avec le meme résultat

  8. #8
    Membre éclairé Avatar de Vesperal
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 81
    Par défaut
    Hmmm ... je ne sais pas à propos de ton code, mais mon navigateur affichait bien la source entière de la page de google par exemple.

    Ca ne doit donc pas se situer à ce niveau la à mon avis.

  9. #9
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    Citation Envoyé par Vesperal
    je ne sais pas à propos de ton code, mais mon navigateur affichait bien la source entière de la page de google par exemple.
    je suis bien d'accord, c'est pour ca que je peux affirmer que je n'ai pas l'integralité de la page....

    ce qui est bizare c'est que ca me fait pour différentes pages, et pour toute les pages testée je n'ai pas l'integralité...

    Par contre le nombre de caractères diffèrent mais reste aux alentours de 2400-3000.

  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
    Citation Envoyé par @ldehan
    Pour la lecture, mon premier code revient au meme qu'au tiens sauf que je lit tout le reader d'un coup au lieu de lire caractere par caractere dasn une boucle. Mais j'ai essaye les deux avec le meme résultat
    Oui en effet je m'étais focalisé sur le second code... Autant pour moi...

    Toutefois je te conseille d'effectuer une boucle de traitement et de ne pas trop te fier à avaible(), car si la connection est lente (ou que la taille des données est très importante), il peut te renvoyer une valeur inférieur à la taille totale du flux.

    Une boucle avec un read() est plus approprié car elle bloquera jusqu'à la fin du flux (fermeture de la socket par le serveur).



    Citation Envoyé par @ldehan
    J'ai tester avec plusieurs page mais celle que j'ai mis est un bon exemple
    vas sur www.google.fr et affiche la source, puis execute mon code et compare... c'et surprenant.
    Il semblerait que Google envoi du code différent selon le navigateur... et qu'il te considère comme un vieux navigateur. Donc il t'envoit simplement le code HTML... alors qu'il envoit beaucoups de JavaScript aux navigateurs...

    Il faut donc que tu changes le user-agent pour te faire passer pour un autre navigateur, ce qui donne :
    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
    	public static String download(String urlString) throws IOException {
    		URL url = new URL(urlString);
    		URLConnection conn = url.openConnection();
    		conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2");
    		conn.connect();
    		InputStreamReader  inputReader = new InputStreamReader(conn.getInputStream());
    		try{
    			StringBuffer content = new StringBuffer();
    			char[] c = new char[2048];
    			int r;
     
    			while ( (r=inputReader.read(c)) > 0 ) {
    					content.append(c,0,r);
    			}
    			//System.out.println(content.length() + " caractères lus.");
    			return content.toString();
    		}
    		finally{
    			inputReader.close();
    		}
    	}
    Sans User-Agent : 2767 caractères lus.
    Avec celui de Firefox (cf code ci dessus) : 3311 caractères lus.
    Avec celui d'IE6 ("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)") : 3702 caractères lus.

    a++

  11. #11
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    243683 caractères lus.
    c'etait donc ca... ne pas se fier au available()

    voila donc le code tel que je l'ai testé.

    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
            URL url = null;
            InputStream stream = null;
            InputStreamReader inputReader = null;
            try{
               url = new URL("http://www.google.fr");
               stream = url.openStream();
               inputReader = new InputStreamReader(stream);
               StringBuffer content = new StringBuffer();
               char[] chars = new char[2048];
               int r = 0;
               while((r = inputReader.read()) > 0)
                   content.append(chars, 0, r);
               System.out.println(content.length() + " caractères lus.");
            }
            catch(Exception e){
                System.out.println(e.getMessage());           
            }
            finally{
                inputReader.close();
            }
    merci adiGuba et les autres pour leur participation

    Pour ce qui est du user-agent, la finalité n'est pas d'accéder aux pages de google mais je penserais a vérifié si j'ai un code différent selon le navigateur (je pense que je serais passer a coté de ce genre de truc). merci encore.

  12. #12
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    une derniere question toute bête :

    comment on met le tag ? la je l'ai écrit en dur dans le titre mais ca doit pas être ca....

  13. #13
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Tu as le bouton en bas à gauche
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  14. #14
    Membre expérimenté Avatar de @ldehan
    Profil pro
    Développeur Java
    Inscrit en
    Mars 2004
    Messages
    215
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 215
    Par défaut
    simple et efficace ! j'adore

  15. #15
    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 @ldehan
    comment on met le tag ? la je l'ai écrit en dur dans le titre mais ca doit pas être ca....
    Il suffit de cliquer sur le bouton en bas à gauche de la page...

    a++

    [edit] oups trop lent

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Taille InputStream / méthode available
    Par Arnard dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 16/05/2009, 14h42
  2. [String][InputStream]Conversion de l'un a l'autre
    Par 2000 dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 14/10/2004, 12h03
  3. Transformer un String en InputStream
    Par felix79 dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 07/07/2004, 12h18
  4. Transformer un OutputStream en un InputStream
    Par glRaZ dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 29/04/2004, 11h10
  5. [Servlet][IO]Ecrire un File à partir d'un InputStream
    Par ravioli dans le forum Servlets/JSP
    Réponses: 4
    Dernier message: 04/02/2004, 10h15

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