Ada file online (seperti http://www.example.com/information.asp
) yang perlu saya ambil dan simpan ke direktori. Saya tahu ada beberapa metode untuk mengambil dan membaca file online (URL) baris-demi-baris, tetapi apakah ada cara untuk mengunduh dan menyimpan file menggunakan Java?
425
Jawaban:
Berikan Java NIO mencoba:
Menggunakan
transferFrom()
ini berpotensi jauh lebih efisien daripada loop sederhana yang membaca dari saluran sumber dan menulis untuk saluran ini. Banyak sistem operasi dapat mentransfer byte langsung dari saluran sumber ke cache sistem file tanpa benar-benar menyalinnya.Lihat lebih lanjut di sini .
Catatan : Parameter ketiga dalam transferFrom adalah jumlah byte maksimum untuk ditransfer.
Integer.MAX_VALUE
akan mentransfer paling banyak 2 ^ 31 byte,Long.MAX_VALUE
akan memungkinkan paling banyak 2 ^ 63 byte (lebih besar dari file apa pun yang ada).sumber
8388608
TB?transferFrom()
tidak ditentukan untuk menyelesaikan seluruh transfer dalam satu panggilan. Itu sebabnya ia mengembalikan hitungan. Anda harus mengulang.URL::openStream()
mengembalikan hanya aliran biasa, artinya seluruh lalu lintas masih sedang disalin melalui array Java byte [] alih-alih tetap di buffer asli. Hanyafos.getChannel()
sebenarnya saluran asli, sehingga overhead tetap penuh. Itu nol keuntungan dari menggunakan NIO dalam kasus ini. Selain rusak, seperti yang EJP dan Ben MacCann perhatikan dengan benar.Gunakan apache commons-io , hanya satu kode baris:
sumber
copyURLToFile
dengan parameter batas waktu hanya tersedia sejak versi 2.0 dari perpustakaan Commons IO. Lihat dokumen JavaPenggunaan nio yang lebih sederhana:
sumber
InputStream.read()
mengembalikan nol kecuali Anda memberikan buffer panjang nol atau menghitung, 'jeda sedikit' atau sebaliknya. Itu akan memblokir hingga setidaknya satu byte telah ditransfer atau akhir aliran atau kesalahan terjadi. Klaim Anda tentang masalah internalFiles.copy()
tidak berdasar.Anda harus menangani pengecualian, mungkin eksternal dari metode ini.
sumber
in.close
melempar pengecualian,fout.close
tidak dipanggil.BufferedInputStream
efek nol pada timeout soket. Saya sudah membantahnya sebagai 'mitos urban' dalam komentar saya pada 'detail latar belakang' yang Anda kutip. Tiga tahun sebelumnya.BufferedInputStream
"dapat menyebabkan kegagalan yang tidak terduga").Ini adalah pertanyaan lama tapi di sini ada solusi JDK yang ringkas, mudah dibaca, dan hanya dengan sumber daya yang ditutup dengan benar:
Dua baris kode dan tidak ada dependensi.
sumber
import java.io.InputStream; import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths;
Mengunduh file mengharuskan Anda membacanya, dengan cara apa pun Anda harus membaca file dengan cara apa pun. Alih-alih baris demi baris, Anda bisa membacanya dengan byte dari aliran:
sumber
Saat menggunakan
Java 7+
gunakan metode berikut untuk mengunduh file dari Internet dan menyimpannya ke beberapa direktori:Dokumentasi di sini .
sumber
Jawaban ini hampir persis seperti jawaban yang dipilih tetapi dengan dua perangkat tambahan: ini adalah metode dan menutup objek FileOutputStream:
sumber
transferFrom()
tidak ditentukan untuk menyelesaikan seluruh transfer dalam satu panggilan. Itu sebabnya ia mengembalikan hitungan. Anda harus mengulang.sumber
in.close
melempar pengecualian,out.close
tidak dipanggil.Secara pribadi, saya menemukan HttpClient Apache lebih dari mampu melakukan semua yang saya perlu lakukan sehubungan dengan ini. Ini adalah tutorial yang bagus untuk menggunakan HttpClient
sumber
Ini adalah varian java7 lain berdasarkan jawaban Brian Risk dengan penggunaan pernyataan coba-dengan:
sumber
transferFrom()
tidak ditentukan untuk menyelesaikan seluruh transfer dalam satu panggilan. Itu sebabnya ia mengembalikan hitungan. Anda harus mengulang.Mungkin untuk mengunduh file dengan menggunakan Apache,
HttpComponents
bukanCommons-IO
. Kode ini memungkinkan Anda untuk mengunduh file di Jawa sesuai dengan URL-nya dan menyimpannya di tujuan tertentu.Berbeda dengan satu baris kode:
kode ini akan memberi Anda lebih banyak kontrol atas suatu proses dan memungkinkan Anda menentukan tidak hanya waktu menyendiri tetapi
User-Agent
danReferer
nilai - nilai, yang sangat penting bagi banyak situs web.sumber
Ada banyak jawaban yang elegan dan efisien di sini. Tetapi keringkasan ini dapat membuat kita kehilangan beberapa informasi yang bermanfaat. Secara khusus, orang sering tidak ingin menganggap kesalahan koneksi sebagai Pengecualian , dan orang mungkin ingin memperlakukan secara berbeda beberapa jenis kesalahan terkait jaringan - misalnya, untuk memutuskan apakah kami harus mencoba ulang unduhan.
Berikut adalah metode yang tidak membuang Pengecualian untuk kesalahan jaringan (hanya untuk masalah yang benar-benar luar biasa, seperti url yang salah format atau masalah menulis ke file)
sumber
Di bawah ini adalah contoh kode untuk mengunduh film dari internet dengan kode java:
sumber
Ada masalah dengan penggunaan sederhana:
jika Anda perlu mengunduh dan menyimpan file yang sangat besar, atau secara umum jika Anda perlu mencoba ulang otomatis jika koneksi terputus.
Apa yang saya sarankan dalam kasus tersebut adalah Apache HttpClient bersama dengan org.apache.commons.io.FileUtils. Sebagai contoh:
sumber
Untuk meringkas (dan entah bagaimana memoles dan memperbarui) jawaban sebelumnya. Tiga metode berikut ini praktis setara. (Saya menambahkan batas waktu eksplisit karena saya pikir itu adalah keharusan, tidak ada yang mau unduhan dibekukan selamanya ketika koneksi terputus.)
Saya tidak menemukan perbedaan yang signifikan, semuanya tampak benar bagi saya. Mereka aman dan efisien. (Perbedaan kecepatan tampaknya hampir tidak relevan - saya menulis 180MB dari server lokal ke disk SSD pada waktu yang berfluktuasi sekitar 1,2 hingga 1,5 seg). Mereka tidak memerlukan perpustakaan eksternal. Semua bekerja dengan ukuran sewenang-wenang dan (untuk pengalaman saya) pengalihan HTTP.
Selain itu, semua melempar
FileNotFoundException
jika sumber daya tidak ditemukan (kesalahan 404, biasanya), danjava.net.UnknownHostException
jika resolusi DNS gagal; IOException lainnya berhubungan dengan kesalahan selama transmisi.(Ditandai sebagai komunitas wiki, silakan tambahkan info atau koreksi)
sumber
Ada metode U.fetch (url) di underscore-java perpustakaan .
pom.xml:
Contoh kode:
sumber
Java
, tetapi jawaban Anda terlihat sepertiJavaScript
sumber
Anda dapat melakukan ini dalam 1 baris menggunakan netloader untuk Java :
sumber
Jika Anda berada di belakang proxy, Anda dapat mengatur proksi dalam program java seperti di bawah ini:
Jika Anda tidak berada di belakang proxy, jangan sertakan baris di atas dalam kode Anda. Kode kerja penuh untuk mengunduh file saat Anda berada di belakang proxy.
sumber
Metode 1 menggunakan saluran baru
Metode 2 menggunakan FileUtils
Metode 3 menggunakan
Ini adalah bagaimana kita dapat mengunduh file dengan menggunakan kode java dasar dan perpustakaan pihak ketiga lainnya. Ini hanya untuk referensi cepat. Silakan google dengan kata kunci di atas untuk mendapatkan informasi rinci dan opsi lainnya.
sumber