Önceki cevapları özetlemek (ve bir şekilde cilalamak ve güncellemek). Aşağıdaki üç yöntem pratik olarak eşdeğerdir. (Açık zaman aşımları ekledim, çünkü bunların bir zorunluluk olduğunu düşünüyorum, kimse bağlantı kesildiğinde bir indirme işleminin sonsuza kadar donmasını istemiyor.)
public static void saveUrl1(final Path file, final URL url,
int secsConnectTimeout, int secsReadTimeout))
throws MalformedURLException, IOException {
// Files.createDirectories(file.getParent()); // optional, make sure parent dir exists
try (BufferedInputStream in = new BufferedInputStream(
streamFromUrl(url, secsConnectTimeout,secsReadTimeout) );
OutputStream fout = Files.newOutputStream(file)) {
final byte data[] = new byte[8192];
int count;
while((count = in.read(data)) > 0)
fout.write(data, 0, count);
}
}
public static void saveUrl2(final Path file, final URL url,
int secsConnectTimeout, int secsReadTimeout))
throws MalformedURLException, IOException {
// Files.createDirectories(file.getParent()); // optional, make sure parent dir exists
try (ReadableByteChannel rbc = Channels.newChannel(
streamFromUrl(url, secsConnectTimeout,secsReadTimeout)
);
FileChannel channel = FileChannel.open(file,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)
) {
channel.transferFrom(rbc, 0, Long.MAX_VALUE);
}
}
public static void saveUrl3(final Path file, final URL url,
int secsConnectTimeout, int secsReadTimeout))
throws MalformedURLException, IOException {
// Files.createDirectories(file.getParent()); // optional, make sure parent dir exists
try (InputStream in = streamFromUrl(url, secsConnectTimeout,secsReadTimeout) ) {
Files.copy(in, file, StandardCopyOption.REPLACE_EXISTING);
}
}
public static InputStream streamFromUrl(URL url,int secsConnectTimeout,int secsReadTimeout) throws IOException {
URLConnection conn = url.openConnection();
if(secsConnectTimeout>0) conn.setConnectTimeout(secsConnectTimeout*1000);
if(secsReadTimeout>0) conn.setReadTimeout(secsReadTimeout*1000);
return conn.getInputStream();
}
Önemli farklılıklar bulamıyorum, hepsi benim için doğru görünüyor. Güvenli ve verimlidirler. (Hız farkları pek alakalı görünmüyor - yerel sunucudan bir SSD diskine yaklaşık 1.2 ila 1.5 seg dalgalanan zamanlarda 180Mb yazıyorum). Harici kütüphanelere ihtiyaç duymazlar. Tümü keyfi boyutlarda ve (deneyimime göre) HTTP yeniden yönlendirmeleriyle çalışır.
Buna ek olarak, FileNotFoundException
kaynak bulunamazsa (genellikle 404 hatası) ve java.net.UnknownHostException
DNS çözümlemesi başarısız olursa tümü atar ; diğer IOException iletim sırasındaki hatalara karşılık gelir.
(Topluluk wiki'si olarak işaretlendi, bilgi veya düzeltme eklemekten çekinmeyin)