Le téléchargement de fichiers à partir d'une URL réseau vers un répertoire local est une opération couarnte dans les applications Java. Cette fonctionnalité doit gérer plusieurs aspects : la récupération fiable du contenu distant, la détection du type de fichier (extension), et la sauvegarde locale avec un nom personnalisé si nécessaire. Prenons comme exemple l'URL suivante, extraite d'un site public de documents académiques :
https://papers.xtremepape.rs/.../da1_2002_dec_a.pdf
Cette ressource est un document PDF accessible publiquement. L’objectif est de télécharger ce fichier tout en extrayant correctement son extension, même si le nom final local est partiellement ou totalement personnalisé.
Approche simplifiée avec Apache Commons IO
La bibliothèque commons-io propose des utilitaires puissants pour manipuler les flux et les fichiers. La méthode copyURLToFile() permet de télécharger directement une ressource distante sans avoir à gérer manuellement les flux d'entrée/sortie.
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.net.URL;
public class WebDownloader {
public static void telechargerAvecCommons(String urlTexte, String nomPersonnalisé, String repertoireCible) {
try {
URL source = new URL(urlTexte);
File dossier = new File(repertoireCible);
if (!dossier.exists() && !dossier.mkdirs()) {
System.err.println("Impossible de créer le répertoire : " + repertoireCible);
return;
}
String nomFinal = genererNomFichier(source, nomPersonnalisé);
File destination = new File(dossier, nomFinal);
FileUtils.copyURLToFile(source, destination);
System.out.println("Téléchargé vers : " + destination.getAbsolutePath());
} catch (Exception e) {
System.err.println("Échec du téléchargement : " + e.getMessage());
}
}
}
Implémentation manuelle avec HttpURLConnection
Pour plus de contrôle (comme la gestion des en-têtes HTTP ou les délais personnalisés), on peut utiliser URLConnection avec des flux bruts. Cette approche permet notamment d'imiter un navigateur via l’en-tête User-Agent, ce qui évite certains blocages par les serveurs.
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
public class RawDownloader {
public static void telechargerManuel(String urlTexte, String nomBase, String cheminSortie) {
InputStream entree = null;
OutputStream sortie = null;
long tailleTotale = 0;
try {
URL cible = new URL(urlTexte);
URLConnection connexion = cible.openConnection();
connexion.setConnectTimeout(5000);
connexion.setRequestProperty("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
entree = connexion.getInputStream();
File repertoire = new File(cheminSortie);
if (!repertoire.exists()) {
repertoire.mkdirs();
}
String nomFinal = genererNomFichier(cible, nomBase);
File fichierSortie = new File(repertoire, nomFinal);
sortie = new FileOutputStream(fichierSortie);
byte[] tampon = new byte[1024];
int lu;
while ((lu = entree.read(tampon)) != -1) {
sortie.write(tampon, 0, lu);
tailleTotale += lu;
}
System.out.printf("Fichier '%s' téléchargé (%d octets)%n", nomFinal, tailleTotale);
} catch (IOException e) {
System.err.println("Erreur réseau : " + e.getMessage());
} finally {
fermerSilencieusement(entree);
fermerSilencieusement(sortie);
}
}
private static String genererNomFichier(URL url, String suggestion) {
if (suggestion == null || suggestion.trim().isEmpty()) {
suggestion = String.valueOf(System.currentTimeMillis());
}
String chemin = url.getPath();
int point = chemin.lastIndexOf('.');
if (point != -1 && point > chemin.lastIndexOf('/')) {
String extension = chemin.substring(point);
return suggestion + extension;
}
return suggestion;
}
private static void fermerSilencieusement(Closeable ressource) {
if (ressource != null) {
try {
ressource.close();
} catch (IOException ignored) {}
}
}
}
Dépendance Maven requise
Pour utiliser la version simplifiée avec FileUtils, ajoutez cette dépendance dans votre pom.xml :
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
Exemple d’utilisation
public static void main(String[] args) {
String lienPdf = "https://papers.xtremepape.rs/.../da1_2002_dec_a.pdf";
String dossierLocal = "C:/telechargements";
// Version simple
telechargerAvecCommons(lienPdf, "document_officiel", dossierLocal);
// Version contrôlée
telechargerManuel(lienPdf, "rapport_acca", dossierLocal);
}
Ces deux approches permettent un téléchargement efficace. Le choix dépend du besoin en personnalisation et de la volonté d’éviter les dépendances externes.