Jest plik online (taki jak http://www.example.com/information.asp
), który muszę pobrać i zapisać w katalogu. Wiem, że istnieje kilka metod pobierania i odczytywania plików online (adresów URL) wiersz po wierszu, ale czy istnieje sposób, aby po prostu pobrać i zapisać plik przy użyciu Java?
425
Odpowiedzi:
Wypróbuj Java NIO :
Korzystanie
transferFrom()
jest potencjalnie znacznie bardziej wydajne niż prosta pętla, która czyta z kanału źródłowego i zapisuje na tym kanale. Wiele systemów operacyjnych może przesyłać bajty bezpośrednio z kanału źródłowego do pamięci podręcznej systemu plików bez ich kopiowania.Sprawdź więcej na ten temat tutaj .
Uwaga : Trzecim parametrem w TransferFrom jest maksymalna liczba bajtów do przesłania.
Integer.MAX_VALUE
przesyła najwyżej 2 ^ 31 bajtów,Long.MAX_VALUE
pozwala na maksymalnie 2 ^ 63 bajtów (więcej niż jakikolwiek istniejący plik).źródło
8388608
TB?transferFrom()
isnt ”, aby zakończyć cały transfer w jednym połączeniu. Dlatego zwraca liczbę. Musisz zapętlić.URL::openStream()
zwraca tylko zwykły strumień, co oznacza, że cały ruch jest nadal kopiowany przez tablice bajtów Java [] zamiast pozostać w natywnych buforach. Wfos.getChannel()
rzeczywistości jest to tylko kanał macierzysty, więc narzut pozostaje cały. To zero korzyści z używania NIO w tym przypadku. Oprócz zepsucia, jak słusznie zauważyli EJP i Ben MacCann.Użyj apache commons-io , tylko jeden kod wiersza:
źródło
copyURLToFile
parametr timeout jest dostępny tylko od wersji 2.0 biblioteki Commons IO. Zobacz dokumenty JavaProstsze użycie nio:
źródło
InputStream.read()
chyba że podasz bufor lub licznik o zerowej długości, „małą pauzę” lub w inny sposób. Będzie blokował się, dopóki przynajmniej jeden bajt nie zostanie przesłany, koniec strumienia lub wystąpi błąd. Twoje roszczenie dotyczące elementów wewnętrznychFiles.copy()
jest bezpodstawne.Będziesz musiał obsługiwać wyjątki, prawdopodobnie zewnętrzne dla tej metody.
źródło
in.close
zgłasza wyjątek,fout.close
nie jest wywoływany.BufferedInputStream
ma dokładnie zerowy wpływ na przekroczenie limitu czasu gniazda. Odrzuciłem to już jako „miejski mit” w moich komentarzach do „szczegółów tła”, które zacytowałeś. 3 lata wcześniejBufferedInputStream
„może powodować nieprzewidziane awarie”).To stare pytanie, ale tutaj jest zwięzłe, czytelne rozwiązanie tylko dla JDK z odpowiednio zamkniętymi zasobami:
Dwa wiersze kodu i brak zależności.
źródło
import java.io.InputStream; import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths;
Pobranie pliku wymaga przeczytania go, tak czy inaczej, będziesz musiał przejść przez plik w jakiś sposób. Zamiast linii po linii możesz po prostu odczytać bajty ze strumienia:
źródło
Podczas korzystania
Java 7+
użyć metody następujące pobrać plik z Internetu i zapisać go w jakimś katalogu:Dokumentacja tutaj .
źródło
Ta odpowiedź jest prawie dokładnie tak, jak wybrana odpowiedź, ale z dwoma ulepszeniami: jest to metoda i zamyka obiekt FileOutputStream:
źródło
transferFrom()
isnt ”, aby zakończyć cały transfer w jednym połączeniu. Dlatego zwraca liczbę. Musisz zapętlić.źródło
in.close
zgłasza wyjątek,out.close
nie jest wywoływany.Osobiście uważam, że HttpClient Apache'a jest więcej niż zdolny do wszystkiego, co muszę zrobić w związku z tym. Oto świetny samouczek na temat korzystania z HttpClient
źródło
To kolejny wariant java7 oparty na odpowiedzi Briana Risk'a z użyciem instrukcji try-with:
źródło
transferFrom()
isnt ”, aby zakończyć cały transfer w jednym połączeniu. Dlatego zwraca liczbę. Musisz zapętlić.Możliwe jest pobranie pliku za pomocą Apache
HttpComponents
zamiastCommons-IO
. Ten kod umożliwia pobranie pliku w Javie zgodnie z jego adresem URL i zapisanie go w określonym miejscu docelowym.W przeciwieństwie do pojedynczej linii kodu:
ten kod da ci większą kontrolę nad procesem i pozwoli ci określić nie tylko limity czasu, ale
User-Agent
iReferer
wartości, które są kluczowe dla wielu stron internetowych.źródło
Istnieje tutaj wiele eleganckich i skutecznych odpowiedzi. Ale zwięzłość może sprawić, że stracimy przydatne informacje. W szczególności często nie chce się uważać błędu połączenia za wyjątek i można potraktować inaczej niektóre rodzaje błędów związanych z siecią - na przykład, aby zdecydować, czy należy ponowić próbę pobrania.
Oto metoda, która nie zgłasza wyjątków dla błędów sieciowych (tylko w przypadku naprawdę wyjątkowych problemów, takich jak nieprawidłowy adres URL lub problemy z zapisywaniem do pliku)
źródło
Poniżej znajduje się przykładowy kod do pobrania filmu z Internetu za pomocą kodu Java:
źródło
Występuje problem z prostym użyciem:
jeśli musisz pobrać i zapisać bardzo duże pliki lub ogólnie, jeśli potrzebujesz automatycznych prób w przypadku utraty połączenia.
W takich przypadkach sugeruję Apache HttpClient wraz z org.apache.commons.io.FileUtils. Na przykład:
źródło
Podsumowując (i jakoś dopracowując i aktualizując) poprzednie odpowiedzi. Trzy następujące metody są praktycznie równoważne. (Dodałem wyraźne limity czasu, ponieważ uważam, że są koniecznością, nikt nie chce, aby pobieranie zawieszało się na zawsze po utracie połączenia).
Nie widzę istotnych różnic, wszystko wydaje mi się właściwe. Są bezpieczne i wydajne. (Różnice prędkości wydają się mało istotne - zapisuję 180 MB z lokalnego serwera na dysk SSD w czasach, które wahają się w granicach od 1,2 do 1,5 seg). Nie wymagają zewnętrznych bibliotek. Wszystkie działają z dowolnymi rozmiarami i (według mojego doświadczenia) przekierowaniami HTTP.
Ponadto wszystkie rzucają,
FileNotFoundException
jeśli zasób nie zostanie znaleziony (zwykle błąd 404), orazjava.net.UnknownHostException
jeśli nie powiodło się rozstrzyganie DNS; inne wyjątki IOException odpowiadają błędom podczas transmisji.(Oznaczone jako wiki społeczności, dodaj informacje lub poprawki)
źródło
Istnieje metoda U.fetch (url) w bibliotece podkreślenia-java .
pom.xml:
Przykład kodu:
źródło
Java
, ale twoja odpowiedź wygląda jakJavaScript
źródło
Możesz to zrobić w 1 linii za pomocą netloader dla Java :
źródło
Jeśli jesteś za proxy, możesz ustawić proxy w programie Java w następujący sposób:
Jeśli nie jesteś za serwerem proxy, nie dołączaj powyższych wierszy do kodu. Pełny działający kod do pobrania pliku, gdy jesteś za serwerem proxy.
źródło
Pierwsza metoda przy użyciu nowego kanału
Druga metoda przy użyciu FileUtils
3. metoda przy użyciu
W ten sposób możemy pobrać plik za pomocą podstawowego kodu Java i innych bibliotek stron trzecich. Są to tylko dla szybkiego odniesienia. Przejdź do Google przy użyciu powyższych słów kluczowych, aby uzyskać szczegółowe informacje i inne opcje.
źródło