Schnelleres Speichern von XML-Daten über URLConnection

Maliko

Bekanntes Mitglied
Hoi,

ich hab da mal ne Frage. Und zwar habe ich ein kleines Tool, was eine Webseite ansurft und die XML die es zurückerhält (ist ne Schnittstelle) als Datei speichert. Das Problem ist, dass die Dateien die zurückkommen locker mal 200 - 300 kb Groß sind und es daher durchaus bis zu 5 Sekunden dauern kann, bis er einmal durch den kompletten BufferedReader geeiert ist. Ich will eigenlich einfach nur den Response der Webseite (ist ne API) die immer XML zurückgibt in eine Datei schmeißen. Sprich zwischendrin findet keine Verarbeitung statt. Diese findet erst im Anschluss statt.

Daher meine Frage. Gibt es eine Möglichkeit irgendwie den gesamten Inhalt eines Readers in eine Datei zu dumpen und nicht den Umweg über Zeilenweises einlesen zu gehen? eine Funktion ReadToEnd() gibt es leider nicht.

Folgende Funktion nutze ich bisher:
Java:
private void GetXML(String urlRaw, String filePath) throws MalformedURLException, IOException {
        URL url = new URL(urlRaw);       

        HttpsURLConnection.setDefaultHostnameVerifier((host, sess) -> "aspserver.topm.de".equals(host));
        URLConnection request = (HttpsURLConnection)url.openConnection();
        BufferedWriter sw;
        
        try (BufferedReader sr = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
            sw = new BufferedWriter(new FileWriter(new File(filePath)));
            String line;
            
            while ((line = sr.readLine()) != null) {
                sw.write(line);
            }
        }
        sw.close();
    }

Würde mich über nen Tipp wie ich das beschleunigen könnte wirklich freuen. Momentan kostet mich nämlich nur das Erstellen von ungefähr 25 XMLs schon fast 3 Minuten und das ist einfach zu lange. Ich bedanke mich schon mal im Vorraus für eure Hilfe.
 
Zusätzlich könntest Du mal mehrere Threads verwenden, um Latenzzeiten besser zu nutzen. Der Browser lädt die Ressourcen auch nicht nacheinander herunter 🙂
 
Vielen Dank für eure beiden Tipps. Die von LimDul hat leider nicht funktioniert, weil die Funktion erst ab Java 9 zur Verfügung steht und bei uns in der Firma noch mit Java 8 gearbeitet wird.

Aber der Tipp mit dem Multithreading hat definitiv was gebracht. Da ich mir die XMLs jetzt alle gleichzeitig ziehe, bin ich nur noch bei knapp 30 Sekunden für alle zusammen.
 
Die Dokumentation von BufferedReader sagt es doch bereits:
Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.
Rohes read und write mit einem byte-Array sollte deutlich schneller sein. Und ein Blick auf die Implementierung der Java 9 Funktion "InputStream.transferTo" zeigt, wie es performanter umzusetzen ist:
Java:
public long transferTo(OutputStream out) throws IOException {
    Objects.requireNonNull(out, "out");
    long transferred = 0;
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    int read;
    while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
        out.write(buffer, 0, read);
        transferred += read;
    }
    return transferred;
}
Also einfach diesen Code kopieren und in eine static-Methode mit zusätzlichem InputStream-Parameter umbauen.
 

Zurück
Oben