C'è un motivo per utilizzare BufferedReader su InputStreamReader durante la lettura di tutti i caratteri?

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

Domanda

Attualmente utilizzo la seguente funzione per eseguire un semplice 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();
}

Non vedo alcun motivo per utilizzare il file BufferedReader poiché scaricherò tutto in sequenza.Ho ragione nel pensare che non vi sia alcuna utilità per il file BufferedReader in questo caso?

È stato utile?

Soluzione

In questo caso, farei come stai facendo tu (utilizzare un array di byte per il buffering e non uno dei buffer del flusso).

Ci sono delle eccezioni, però.Un posto in cui vedi i buffer (output questa volta) è nell'API servlet.I dati non vengono scritti nel flusso sottostante fino a quando sciacquone() viene chiamato, permettendoti di bufferizzare l'output ma poi di scaricare il buffer se si verifica un errore e scrivere invece una pagina di errore.Potresti bufferizzare l'input se fosse necessario reimpostare il flusso per la rilettura utilizzando segno(int) E Ripristina().Ad esempio, potresti ispezionare l'intestazione del file prima di decidere a quale gestore di contenuti passare lo stream.

Non correlato, ma penso che dovresti riscrivere la gestione del flusso.Questo modello funziona meglio per evitare perdite di risorse:

    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();
    }

Se stai aprendo più flussi, annida prova/finalmente blocca.

Un'altra cosa che il tuo codice sta facendo è presupporre che il contenuto restituito sia codificato nel set di caratteri predefinito della tua VM (anche se ciò potrebbe essere adeguato, a seconda del caso d'uso).

Altri suggerimenti

Hai ragione, se usi BufferedReader per leggere contenuto e intestazioni HTTP, vorrai InputStreamReader in modo da poter leggere byte per byte.

BufferedReader in questo scenario a volte fa cose strane... soprattutto quando si tratta di leggere le intestazioni HTTP POST, a volte non sarai in grado di leggere i dati POST, se usi InputStreamReader puoi leggere la lunghezza del contenuto e leggere tanti byte. .

Ogni invocazione di uno di an InputStreamReaderI metodi read() di possono causare la lettura di uno o più byte dal flusso di input di byte sottostante.Per consentire la conversione efficiente di byte in caratteri, è possibile leggere in anticipo dal flusso sottostante più byte di quelli necessari per soddisfare l'operazione di lettura corrente.

Il mio istinto mi dice che dal momento che stai già eseguendo il buffering utilizzando l'array di byte, è ridondante utilizzare BufferedReader.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top