9
votes

Bufferedreader ne sait pas "prêt" quand il devrait

J'essaie de lire du texte à partir d'un document Web à l'aide d'un fichier bufferedreader sur une URL (dans le fichier sur certains serveur Apache). XXX

Maintenant cela fonctionne juste bien. Mais évidemment, j'aimerais que le lecteur ne suffit pas à lire une ligne, mais autant qu'il y a dans le dossier.
En regardant l'API de bufferedreader, le code suivant doit faire exactement que: xxx

I.e. Lisez toutes les lignes pendant qu'il y ait plus de lignes, arrêtez-vous quand il n'y a plus de lignes. Ce code ne fonctionne pas cependant - le lecteur juste jamais rapports prêt () = true !

i peut même imprimer la valeur prête () juste avant lire une ligne (qui lit la chaîne correcte du fichier) mais le lecteur signalera ' faux '.

suis-je en train de faire quelque chose de mal? Pourquoi la bufferedreader retourne-t-elle ' faux ' sur prête quand il y a des choses à lire?


3 commentaires

Je ne sais pas si cela est d'une importance, mais l'URL pointe réellement un emplacement à l'aide de HTTPS. Les certificats sont cependant correctement installés sur le serveur et sur la machine qui exécute le code ci-dessus. De plus, le readline () renvoie la première ligne sans problèmes.


Il sera prêt quand il y a des données en attente, mais il n'aura pas d'attendre des données avant d'effectuer une lecture / readline. Même s'il y a des données en attente, il peut ne pas être une ligne complète, alors readline () bloquera de toute façon.


Lotta Great Answers, Thx tous. Malheureusement, je ne peux que marquer une seule réponse acceptée. :)


7 Réponses :


6
votes

Une autre façon que vous pouvez faire cela qui contourne le in.REady () est quelque chose comme: xxx

Vous continuerez à lire jusqu'à ce que vous ayez terminé. De cette façon, vous n'avez pas besoin de vous inquiéter du problème avec in.ready () .


1 commentaires

Je pense que vous avez compromis votre réponse en faisant sonner comme une solution de contournement. Ce que vous avez montré est l'idiome le plus courant pour la lecture d'une bufferedreader, mais plus important encore, c'est correct. À l'aide de la méthode prêt () comme l'OP a fait est pas correct.



4
votes

Je pense que le moyen standard d'écrire est de tenter de lire la ligne et de vérifier qu'il est retourné de temps en temps. Quelque chose comme ceci: xxx

pour que vous continuiez à aller jusqu'à ce que vous obtenez NULL renvoyé du flux. Voir ici pour des informations supplémentaires:

http://download.oracle.com/javase/1.5.0/docs/api/java/io/bufferedreader.html#readline ()



1
votes

Le bufferedreader.ready () est comportant comme spécifié:

Le Reader.Ready () Javadoc dit ce qui suit:

[retour] true si le prochain lis () est garanti de ne pas bloquer pour l'entrée, false sinon. Notez que le retour faux ne garantit pas que la prochaine lecture bloquera.

alors le Bufferedreader.ready () Javadoc dit ce qui suit:

indique si ce flux est prêt à être lu. Un flux de caractères tampon est prêt si le tampon n'est pas vide, ou si le flux de caractères sous-jacents est prêt .

Si vous mettez ces deux ensemble, il est clair que bufferedreader.ready () peut retour false dans des situations où les caractères sont disponibles. En bref, vous ne devriez pas compter sur prêt () pour tester pour la fin de fichier logique ou la fin de flux.


0 commentaires

10
votes

prêt ()! = a plus

prêt () n'indique pas qu'il y a plus de données à lire. Il ne montre que si une lecture sera pourrait bloquer le fil. Il est probable qu'il retournerait faux avant de lire toutes les données.

Pour savoir s'il n'y a plus de vérification de données si readline () retourne null . xxx


0 commentaires

0
votes

C'est ce que nous utilisons de manière cohérente depuis des années - pas sûr s'il s'agit de la méthode "standard". J'aimerais entendre des commentaires sur les avantages et les inconvénients de l'utilisation directe de l'URL.Openurlstream () et si cela provoque les problèmes de l'OP. Ce code fonctionne pour les connexions HTTP et HTTPS.

 URL  getURL = new URL (servletURL.toString() + identifier+"?"+key+"="+value);      
 URLConnection uConn = getURL.openConnection();

 BufferedReader br = new BufferedReader (new
                            InputStreamReader (uConn.getInputStream()));
 for (String s = br.readLine() ; s != null ; s = br.readLine()) {
      System.out.println ("[ServletOut] " + s);
      // do stuff with s
 }               
 br.close();


0 commentaires

0
votes

Fondamentalement, la méthode bufferedReader.Ready () peut être utilisée pour vérifier si le flux sous-jacent est prêt à fournir des données à l'appelant de la méthode .... sinon, nous pouvons attendre le fil pendant un certain temps.

Mais le vrai problème est qu'après que nous avons complètement lu le flux de données, il va jeter de la fausse .. Nous ne savions donc pas si le flux est complètement lu ou sous-jacent à Stream est occupé ....


1 commentaires

Bienvenue sur Stackoverflow. Assurez-vous de vérifier comment utiliser Mise en forme de Markdown . Ça va rendre vos réponses plus utilisables pour les autres.



0
votes

Si vous voulez utiliser IN.Ready (), les suivants ont fonctionné pour moi bien:

    for (int i = 0; i < 10; i++) {
        System.out.println("is InputStreamReader ready: " + in.ready());
        if (!in.ready()) {
            Thread.sleep(1000);
        } else {
            break;
        }
    }


1 commentaires

Pouvez-vous en dire plus sur votre intention?