Y a-t-il une raison d'utiliser BufferedReader sur InputStreamReader lors de la lecture de tous les caractères ?

StackOverflow https://stackoverflow.com/questions/31380

Question

J'utilise actuellement la fonction suivante pour effectuer un simple HTTP GET.

public static String download(String url) throws java.io.IOException {
    java.io.InputStream s = null;
    java.io.InputStreamReader r = null;
    //java.io.BufferedReader b = null;
    StringBuilder content = new StringBuilder();
    try {
        s = (java.io.InputStream)new URL(url).getContent();

        r = new java.io.InputStreamReader(s);
        //b = new java.io.BufferedReader(r);

        char[] buffer = new char[4*1024];
        int n = 0;
        while (n >= 0) {
            n = r.read(buffer, 0, buffer.length);
            if (n > 0) {
                content.append(buffer, 0, n);
            }
        }
    }
    finally {
        //if (b != null) b.close();
        if (r != null) r.close();
        if (s != null) s.close();
    }
    return content.toString();
}

Je ne vois aucune raison d'utiliser le BufferedReader puisque je vais juste tout télécharger dans l'ordre.Ai-je raison de penser que le BufferedReader dans ce cas?

Était-ce utile?

La solution

Dans ce cas, je ferais comme vous (utilisez un tableau d'octets pour la mise en mémoire tampon et non l'un des tampons de flux).

Il existe cependant des exceptions.Un endroit où vous voyez les tampons (sortie cette fois) est dans l'API du servlet.Les données ne sont écrites dans le flux sous-jacent que lorsque affleurer() est appelé, vous permettant de mettre la sortie en mémoire tampon, puis de vider le tampon si une erreur se produit et d'écrire une page d'erreur à la place.Vous pouvez mettre en mémoire tampon l'entrée si vous devez réinitialiser le flux pour le relire à l'aide de marque(int) et réinitialiser().Par exemple, vous pourriez peut-être inspecter l'en-tête du fichier avant de décider à quel gestionnaire de contenu transmettre le flux.

Sans rapport, mais je pense que vous devriez réécrire la gestion de votre flux.Ce modèle fonctionne mieux pour éviter les fuites de ressources :

    InputStream stream = new FileInputStream("in");
    try { //no operations between open stream and try block
        //work
    } finally { //do nothing but close this one stream in the finally
        stream.close();
    }

Si vous ouvrez plusieurs flux, imbriquez les blocs try/finally.

Une autre chose que fait votre code est de supposer que le contenu renvoyé est codé dans le jeu de caractères par défaut de votre VM (bien que cela puisse être adéquat, selon le cas d'utilisation).

Autres conseils

Vous avez raison, si vous utilisez BufferedReader pour lire le contenu HTTP et les en-têtes, vous aurez besoin d'InputStreamReader pour pouvoir lire octet par octet.

BufferedReader dans ce scénario fait parfois des choses étranges... surtout lorsqu'il s'agit de lire les en-têtes HTTP POST, vous ne pourrez parfois pas lire les données POST, si vous utilisez InputStreamReader, vous pouvez lire la longueur du contenu et lire autant d'octets. .

Chaque invocation d'un d'un Lecteur de flux d'entréeLes méthodes read() de peuvent provoquer la lecture d'un ou plusieurs octets à partir du flux d'entrée d'octets sous-jacent.Pour permettre la conversion efficace des octets en caractères, plus d'octets peuvent être lus à partir du flux sous-jacent que nécessaire pour satisfaire l'opération de lecture en cours.

Mon instinct me dit que puisque vous effectuez déjà une mise en mémoire tampon en utilisant le tableau d'octets, il est redondant d'utiliser BufferedReader.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top