Wie ist der beste Weg, um den gesamten Inhalt von einem BufferedReader-Objekt in Java zu extrahieren?

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

Frage

Ich versuche, eine ganze Webseite durch einen URLConnection zu erhalten.

Was ist der effizienteste Weg, dies zu tun?

Ich mache das schon:

URL url = new URL("http://www.google.com/");
URLConnection connection;
connection = url.openConnection();
InputStream in = connection.getInputStream();        
BufferedReader bf = new BufferedReader(new InputStreamReader(in));
StringBuffer html = new StringBuffer();
String line = bf.readLine();
while(line!=null){
    html.append(line);
    line = bf.readLine();
}
bf.close();

html hat die gesamte HTML-Seite.

War es hilfreich?

Lösung

Ihr Ansatz sieht sehr gut aus, aber können Sie es etwas effizienter machen, indem die Erstellung von Zwischen String-Objekten für jede Zeile zu vermeiden.

Die Art und Weise, dies zu tun ist direkt in ein temporäres Zeichen lesen [] puffer.

Hier ist eine leicht modifizierte Version des Codes, das dies tut (minus all die Fehlerprüfung, Ausnahmebehandlung usw. für Klarheit):

        URL url = new URL("http://www.google.com/");
        URLConnection connection;
        connection = url.openConnection();
        InputStream in = connection.getInputStream();        
        BufferedReader bf = new BufferedReader(new InputStreamReader(in));
        StringBuffer html = new StringBuffer();

        char[] charBuffer = new char[4096];
        int count=0;

        do {
            count=bf.read(charBuffer, 0, 4096);
            if (count>=0) html.append(charBuffer,0,count);
        } while (count>0);
        bf.close();

Für noch mehr Leistung, können Sie natürlich tun wenig zusätzliche Dinge wie Pre-Zuweisung der Zeichenfeld und String wenn dieser Code wird häufig aufgerufen werden.

Andere Tipps

Ich denke, das is die beste Art und Weise. Die Größe der Seite festgelegt ist ( „es ist, was es ist“), so können Sie nicht auf das Gedächtnis zu verbessern. Vielleicht können Sie den Inhalt komprimieren, sobald Sie sie haben, aber sie sind nicht sehr nützlich in dieser Form. Ich könnte mir vorstellen, dass irgendwann werden Sie den HTML-Code in einen DOM-Baum zu analysieren.

Alles, was Sie tun, um die Lesung parallelisieren würde übermäßig die Lösung erschweren.

Ich würde empfehlen, einen String mit einer Standardgröße von 2048 oder 4096 verwendet wird.

Warum denken Sie, dass der Code, den Sie geschrieben nicht ausreicht? Sie klingen wie Sie sich schuldig der vorzeitigen Optimierung sind.

Ausführen mit dem, was Sie haben und Schlaf in der Nacht.

Was wollen Sie mit dem erhaltenen HTML zu tun? Parse es? Es kann gut sein, zu wissen, dass ein bisschen anständige HTML-Parser bereits einen Konstruktor oder eine Methode Argument haben kann, die gerade ein URL oder InputStream nimmt, so dass Sie nicht die Leistung zu sorgen brauchen so über Streaming.

Unter der Annahme, dass alles, was Sie tun mögen, in Ihrer vorherigen Frage beschrieben wird, zum Beispiel mit Jsoup Sie alle diese Nachrichten Links außergewöhnliche leicht erhalten könnte wie folgt:

Document document = Jsoup.connect("http://news.google.com.ar/nwshp?hl=es&tab=wn").get();
Elements newsLinks = document.select("h2.title a:eq(0)");
for (Element newsLink : newsLinks) {
    System.out.println(newsLink.attr("href"));
}

Dies ergibt die folgenden nach nur wenigen Sekunden:

http://www.infobae.com/mundo/541259-100970-0-Pinera-confirmo-que-el-rescate-comenzara-las-20-y-durara-24-y-48-horas
http://www.lagaceta.com.ar/nota/403112/Argentina/Boudou-disculpo-con-DAIA-pero-volvio-cuestionar-medios.html
http://www.abc.es/agencias/noticia.asp?noticia=550415
http://www.google.com/hostednews/epa/article/ALeqM5i6x9rhP150KfqGJvwh56O-thi4VA?docId=1383133
http://www.abc.es/agencias/noticia.asp?noticia=550292
http://www.univision.com/contentroot/wirefeeds/noticias/8307387.shtml
http://noticias.terra.com.ar/internacionales/ecuador-apoya-reclamo-argentino-por-ejercicios-en-malvinas,3361af2a712ab210VgnVCM4000009bf154d0RCRD.html
http://www.infocielo.com/IC/Home/index.php?ver_nota=22642
http://www.larazon.com.ar/economia/Cristina-Fernandez-Censo-indispensable-pais_0_176100098.html
http://www.infobae.com/finanzas/541254-101275-0-Energeticas-llevaron-la-Bolsa-portena-ganancias
http://www.telam.com.ar/vernota.php?tipo=N&idPub=200661&id=381154&dis=1&sec=1
http://www.ambito.com/noticia.asp?id=547722
http://www.canal-ar.com.ar/noticias/noticiamuestra.asp?Id=9469
http://www.pagina12.com.ar/diario/cdigital/31-154760-2010-10-12.html
http://www.lanacion.com.ar/nota.asp?nota_id=1314014
http://www.rpp.com.pe/2010-10-12-ganador-del-pulitzer-destaca-nobel-de-mvll-noticia_302221.html
http://www.lanueva.com/hoy/nota/b44a7553a7/1/79481.html
http://www.larazon.com.ar/show/sdf_0_176100096.html
http://www.losandes.com.ar/notas/2010/10/12/batista-siento-comodo-dieron-respaldo-520595.asp
http://deportes.terra.com.ar/futbol/los-rumores-empiezan-a-complicar-la-vida-de-river-y-vuelve-a-sonar-gallego,a24483b8702ab210VgnVCM20000099f154d0RCRD.html
http://www.clarin.com/deportes/futbol/Exigieron-Roman-regreso-Huracan_0_352164993.html
http://www.el-litoral.com.ar/leer_noticia.asp?idnoticia=146622
http://www.nuevodiarioweb.com.ar/nota/181453/Locales/C%C3%A1ncer_mama:_200_casos_a%C3%B1o_Santiago.html
http://www.ultimahora.com/notas/367322-Funcionarios-sanitarios-capacitaran-sobre-cancer-de-mama
http://www.lanueva.com/hoy/nota/65092f2044/1/79477.html
http://www.infobae.com/policiales/541220-101275-0-Se-suspendio-la-declaracion-del-marido-Fernanda-Lemos
http://www.clarin.com/sociedad/educacion/titulo_0_352164863.html

Hat jemand schon gesagt, dass regex ist absolut das falsche Werkzeug zum Parsen HTML? ;)

Siehe auch:

Sie können versuchen, commons-io von Apache mit (http://commons.apache.org/io/api-release/org/apache/commons/io/IOUtils.html)

new String(IOUtils.toCharArray(connection.getInputStream()))

Es gibt einige technische Überlegungen. Möglicherweise möchten Sie HttpURLConnection verwenden, anstatt URLConnection.

HttpURLConnection unterstützt segmentierte Übertragungscodierung, mit dem Sie die Daten in Blöcken verarbeiten können, anstatt den gesamten Inhalt zu puffern, bevor Sie anfangen zu arbeiten zu tun. Dies kann zu einer besseren Nutzererfahrung führen.

Außerdem unterstützt HttpURLConnection persistente Verbindungen. Warum schließt, dass die Verbindung, wenn Sie eine andere Ressource verlangen sofort gehen? Halten Sie die TCP-Verbindung öffnet mit dem Web-Server ermöglicht, schnell Ihre Anwendung mehr Ressourcen herunterladen, ohne den Aufwand zu verbringen (Latenz), eine neue TCP-Verbindung für jede Ressource aufzubauen.

Bitte geben Sie den Server, dass Sie gzip unterstützen und eine BufferedReader um GZIPInputStream wickeln, wenn die Antwort-Header sagt der Inhalt komprimiert wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top