Es gibt eine Online-Datei (z. B. http://www.example.com/information.asp
), die ich abrufen und in einem Verzeichnis speichern muss. Ich weiß, dass es verschiedene Methoden gibt, um Online-Dateien (URLs) zeilenweise abzurufen und zu lesen, aber gibt es eine Möglichkeit, die Datei einfach mit Java herunterzuladen und zu speichern?
424
Antworten:
Probieren Sie Java NIO aus :
Die Verwendung
transferFrom()
ist möglicherweise viel effizienter als eine einfache Schleife, die aus dem Quellkanal liest und in diesen Kanal schreibt. Viele Betriebssysteme können Bytes direkt vom Quellkanal in den Dateisystem-Cache übertragen, ohne sie tatsächlich zu kopieren.Lesen Sie hier mehr darüber .
Hinweis : Der dritte Parameter in transferFrom ist die maximale Anzahl der zu übertragenden Bytes.
Integer.MAX_VALUE
überträgt höchstens 2 ^ 31 Bytes,Long.MAX_VALUE
erlaubt höchstens 2 ^ 63 Bytes (größer als jede existierende Datei).quelle
8388608
TB will ?transferFrom()
wird nicht angegeben, um die gesamte Übertragung in einem einzigen Anruf abzuschließen. Deshalb gibt es eine Zählung zurück. Du musst eine Schleife machen.URL::openStream()
Gibt nur einen regulären Stream zurück, was bedeutet, dass der gesamte Datenverkehr immer noch über Java-Byte [] -Arrays kopiert wird, anstatt in nativen Puffern zu verbleiben. Nurfos.getChannel()
ist eigentlich ein nativer Kanal, so dass der Overhead voll bleibt. Das ist in diesem Fall kein Gewinn durch die Verwendung von NIO. Abgesehen davon, dass sie kaputt waren, wie EJP und Ben MacCann richtig bemerkten.Verwenden Sie Apache Commons-Io , nur einen Zeilencode:
quelle
copyURLToFile
Parameter timeout erst seit Version 2.0 der Commons IO-Bibliothek verfügbar ist. Siehe Java-DokumenteEinfachere Verwendung:
quelle
InputStream.read()
, Null zurückzugeben, es sei denn, Sie haben einen Puffer oder eine Zählung mit einer Länge von Null, eine kleine Pause oder etwas anderes angegeben. Es wird blockiert, bis mindestens ein Byte übertragen wurde oder das Ende des Streams eintritt oder ein Fehler auftritt. Ihre Behauptung über die Interna vonFiles.copy()
ist unbegründet.Sie müssen Ausnahmen behandeln, wahrscheinlich außerhalb dieser Methode.
quelle
in.close
eine Ausnahme ausgelöst wird,fout.close
wird nicht aufgerufen.BufferedInputStream
hat genau null Auswirkungen auf Socket-Timeouts. Ich hatte dies bereits in meinen Kommentaren zu den von Ihnen zitierten "Hintergrunddetails" als "urbaner Mythos" widerlegt. Drei Jahre zuvor.BufferedInputStream
"unvorhersehbare Fehler verursachen können").Es ist eine alte Frage, aber hier ist eine übersichtliche, lesbare Lösung nur für JDK mit ordnungsgemäß geschlossenen Ressourcen:
Zwei Codezeilen und keine Abhängigkeiten.
quelle
import java.io.InputStream; import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths;
Um eine Datei herunterzuladen, müssen Sie sie lesen. In beiden Fällen müssen Sie die Datei auf irgendeine Weise durchgehen. Anstelle von Zeile für Zeile können Sie es einfach in Bytes aus dem Stream lesen:
quelle
Verwenden Sie bei
Java 7+
Verwendung die folgende Methode, um eine Datei aus dem Internet herunterzuladen und in einem Verzeichnis zu speichern:Dokumentation hier .
quelle
Diese Antwort entspricht fast genau der ausgewählten Antwort, weist jedoch zwei Verbesserungen auf: Es handelt sich um eine Methode, mit der das FileOutputStream-Objekt geschlossen wird:
quelle
transferFrom()
wird nicht angegeben, um die gesamte Übertragung in einem einzigen Anruf abzuschließen. Deshalb gibt es eine Zählung zurück. Du musst eine Schleife machen.quelle
in.close
eine Ausnahme ausgelöst wird,out.close
wird nicht aufgerufen.Persönlich habe ich festgestellt, dass Apaches HttpClient mehr als fähig ist, alles zu tun, was ich dazu tun muss. Hier ist ein großartiges Tutorial zur Verwendung von HttpClient
quelle
Dies ist eine weitere Java7-Variante, die auf der Antwort von Brian Risk unter Verwendung der Try- With-Anweisung basiert :
quelle
transferFrom()
wird nicht angegeben, um die gesamte Übertragung in einem einzigen Anruf abzuschließen. Deshalb gibt es eine Zählung zurück. Du musst eine Schleife machen.Es ist möglich, die Datei mit Apache's
HttpComponents
anstelle von herunterzuladenCommons-IO
. Mit diesem Code können Sie eine Datei in Java entsprechend ihrer URL herunterladen und am jeweiligen Ziel speichern.Im Gegensatz zur einzelnen Codezeile:
Dieser Code wird Ihnen mehr Kontrolle über einen Prozess geben und lassen Sie sich nicht nur Auszeiten geben aber
User-Agent
undReferer
Werte, die für Websites , Web-many kritisch sind.quelle
Hier gibt es viele elegante und effiziente Antworten. Aber die Prägnanz kann dazu führen, dass wir einige nützliche Informationen verlieren. Insbesondere möchte man einen Verbindungsfehler oft nicht als Ausnahme betrachten , und man möchte möglicherweise einige netzwerkbezogene Fehler anders behandeln - zum Beispiel, um zu entscheiden, ob wir den Download wiederholen sollten.
Hier ist eine Methode, die keine Ausnahmen für Netzwerkfehler auslöst (nur für wirklich außergewöhnliche Probleme wie fehlerhafte URLs oder Probleme beim Schreiben in die Datei).
quelle
Unten finden Sie den Beispielcode zum Herunterladen von Filmen aus dem Internet mit Java-Code:
quelle
Es gibt ein Problem mit der einfachen Verwendung von:
Wenn Sie sehr große Dateien herunterladen und speichern müssen oder wenn Sie im Allgemeinen automatische Wiederholungsversuche benötigen, falls die Verbindung unterbrochen wird.
Was ich in solchen Fällen vorschlage, ist Apache HttpClient zusammen mit org.apache.commons.io.FileUtils. Zum Beispiel:
quelle
Um frühere Antworten zusammenzufassen (und irgendwie zu polieren und zu aktualisieren). Die drei folgenden Methoden sind praktisch gleichwertig. (Ich habe explizite Zeitüberschreitungen hinzugefügt, weil ich denke, dass sie ein Muss sind. Niemand möchte, dass ein Download für immer einfriert, wenn die Verbindung unterbrochen wird.)
Ich finde keine signifikanten Unterschiede, alle scheinen mir richtig zu sein. Sie sind sicher und effizient. (Geschwindigkeitsunterschiede scheinen kaum relevant zu sein - ich schreibe 180 MB vom lokalen Server auf eine SSD-Festplatte in Zeiten, die zwischen 1,2 und 1,5 Segmenten schwanken). Sie benötigen keine externen Bibliotheken. Alle arbeiten mit beliebigen Größen und (meiner Erfahrung nach) HTTP-Umleitungen.
Darüber hinaus werden alle ausgelöst,
FileNotFoundException
wenn die Ressource nicht gefunden wird (normalerweise Fehler 404) undjava.net.UnknownHostException
wenn die DNS-Auflösung fehlgeschlagen ist. andere IOException entsprechen Fehlern während der Übertragung.(Als Community-Wiki markiert, können Sie gerne Informationen oder Korrekturen hinzufügen.)
quelle
Es gibt die Methode U.fetch (url) in der Unterstrich-Java- Bibliothek.
pom.xml:
Codebeispiel:
quelle
Java
, aber Ihre Antwort sieht aus wieJavaScript
quelle
Sie können dies mit Netloader für Java in einer Zeile tun :
quelle
Wenn Sie sich hinter einem Proxy befinden, können Sie die Proxys im Java-Programm wie folgt festlegen:
Wenn Sie sich nicht hinter einem Proxy befinden, fügen Sie die obigen Zeilen nicht in Ihren Code ein. Vollständiger Arbeitscode zum Herunterladen einer Datei, wenn Sie sich hinter einem Proxy befinden.
quelle
1. Methode mit dem neuen Kanal
2. Methode mit FileUtils
3. Methode mit
Auf diese Weise können wir Dateien mithilfe von Java-Basiscode und anderen Bibliotheken von Drittanbietern herunterladen. Diese dienen nur als Kurzreferenz. Bitte googeln Sie mit den oben genannten Schlüsselwörtern, um detaillierte Informationen und andere Optionen zu erhalten.
quelle