Comment télécharger et enregistrer un fichier à partir d'Internet en utilisant Java?


Il y a un fichier en ligne (tel que http://www.example.com/information.asp) que je dois saisir et enregistrer dans un répertoire. Je sais qu'il existe plusieurs méthodes pour saisir et lire les fichiers en ligne (URL) ligne par ligne, mais existe-t-il un moyen de simplement télécharger et enregistrer le fichier en utilisant Java?

Author: Rubens Mariuzzo, 2009-05-28

22 answers

Donnez à Java NIO un essai:

URL website = new URL("http://www.website.com/information.asp");
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream("information.html");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);

L'utilisation de transferFrom() est potentiellement beaucoup plus efficace qu'une simple boucle qui lit à partir du canal source et écrit sur ce canal. De nombreux systèmes d'exploitation peuvent transférer des octets directement du canal source dans le cache du système de fichiers sans les copier.

En savoir plusici .

Note: Le troisième paramètre dans transferFrom est le nombre maximal d'octets à transférer. Integer.MAX_VALUE sera transférer au plus 2^31 octets, Long.MAX_VALUE autorisera au plus 2^63 octets (plus grand que n'importe quel fichier existant).

 569
Author: dfa, 2017-12-01 16:32:23

Utilisez apache commons-io , juste un code de ligne:

FileUtils.copyURLToFile(URL, File)
 506
Author: 卢声远 Shengyuan Lu, 2016-10-10 07:40:39

Utilisation plus simple de nio:

URL website = new URL("http://www.website.com/information.asp");
try (InputStream in = website.openStream()) {
    Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
}
 125
Author: xuesheng, 2015-10-23 10:43:14
public void saveUrl(final String filename, final String urlString)
        throws MalformedURLException, IOException {
    BufferedInputStream in = null;
    FileOutputStream fout = null;
    try {
        in = new BufferedInputStream(new URL(urlString).openStream());
        fout = new FileOutputStream(filename);

        final byte data[] = new byte[1024];
        int count;
        while ((count = in.read(data, 0, 1024)) != -1) {
            fout.write(data, 0, count);
        }
    } finally {
        if (in != null) {
            in.close();
        }
        if (fout != null) {
            fout.close();
        }
    }
}

Vous devrez gérer les exceptions, probablement externes à cette méthode.

 86
Author: Ben Noland, 2014-03-16 04:17:20

C'est une vieille question mais voici une solution concise, lisible, uniquement JDK avec des ressources correctement fermées:

import java.io.InputStream;
import java.net.URI;
import java.nio.file.Files; 
import java.nio.file.Paths;

// ...

public static void download(String url, String fileName) throws Exception {
    try (InputStream in = URI.create(url).toURL().openStream()) {
        Files.copy(in, Paths.get(fileName));
    }
}

Deux lignes de code et aucune dépendance.

 26
Author: Jan Nielsen, 2020-09-17 19:24:11

Le téléchargement d'un fichier nécessite de le lire, de toute façon, vous devrez parcourir le fichier d'une manière ou d'une autre. Au lieu de ligne par ligne, vous pouvez simplement le lire par octets à partir du flux:

BufferedInputStream in = new BufferedInputStream(new URL("http://www.website.com/information.asp").openStream())
    byte data[] = new byte[1024];
    int count;
    while((count = in.read(data,0,1024)) != -1)
    {
        out.write(data, 0, count);
    }
 23
Author: z -, 2012-11-04 10:31:06

Lorsque vous utilisez Java 7+ utilisez la méthode suivante pour télécharger un fichier sur Internet et l'enregistrer dans un répertoire:

private static Path download(String sourceURL, String targetDirectory) throws IOException
{
    URL url = new URL(sourceURL);
    String fileName = sourceURL.substring(sourceURL.lastIndexOf('/') + 1, sourceURL.length());
    Path targetPath = new File(targetDirectory + File.separator + fileName).toPath();
    Files.copy(url.openStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);

    return targetPath;
}

Documentation ici.

 17
Author: BullyWiiPlaza, 2017-01-25 18:08:14

Cette réponse est presque exactement comme la réponse sélectionnée mais avec deux améliorations: c'est une méthode et elle ferme l'objet FileOutputStream:

    public static void downloadFileFromURL(String urlString, File destination) {    
        try {
            URL website = new URL(urlString);
            ReadableByteChannel rbc;
            rbc = Channels.newChannel(website.openStream());
            FileOutputStream fos = new FileOutputStream(destination);
            fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
            fos.close();
            rbc.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 16
Author: Brian Risk, 2015-05-28 14:37:01
import java.io.*;
import java.net.*;

public class filedown {
    public static void download(String address, String localFileName) {
        OutputStream out = null;
        URLConnection conn = null;
        InputStream in = null;

        try {
            URL url = new URL(address);
            out = new BufferedOutputStream(new FileOutputStream(localFileName));
            conn = url.openConnection();
            in = conn.getInputStream();
            byte[] buffer = new byte[1024];

            int numRead;
            long numWritten = 0;

            while ((numRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, numRead);
                numWritten += numRead;
            }

            System.out.println(localFileName + "\t" + numWritten);
        } 
        catch (Exception exception) { 
            exception.printStackTrace();
        } 
        finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } 
            catch (IOException ioe) {
            }
        }
    }

    public static void download(String address) {
        int lastSlashIndex = address.lastIndexOf('/');
        if (lastSlashIndex >= 0 &&
        lastSlashIndex < address.length() - 1) {
            download(address, (new URL(address)).getFile());
        } 
        else {
            System.err.println("Could not figure out local file name for "+address);
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            download(args[i]);
        }
    }
}
 10
Author: mumair, 2018-04-12 01:37:57

Personnellement, j'ai trouvéHttpClient d'Apache plus que capable de tout ce que j'ai besoin de faire en ce qui concerne cela. Ici est un excellent tutoriel sur l'utilisation de HttpClient

 8
Author: belgariontheking, 2009-05-28 15:29:17

Ceci est une autre variante java7 basée sur La réponse de Brian Risk avec l'utilisation de l'instruction try-with:

public static void downloadFileFromURL(String urlString, File destination) throws Throwable {

      URL website = new URL(urlString);
      try(
              ReadableByteChannel rbc = Channels.newChannel(website.openStream());
              FileOutputStream fos = new FileOutputStream(destination);  
              ){
          fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
      }

  }
 6
Author: msangel, 2017-05-23 11:54:58

Il est possible de télécharger le fichier avec HttpComponents d'Apache au lieu de Commons-IO. Ce code vous permet de télécharger un fichier en Java selon son URL et l'enregistrer à la destination spécifique.

public static boolean saveFile(URL fileURL, String fileSavePath) {

    boolean isSucceed = true;

    CloseableHttpClient httpClient = HttpClients.createDefault();

    HttpGet httpGet = new HttpGet(fileURL.toString());
    httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
    httpGet.addHeader("Referer", "https://www.google.com");

    try {
        CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity fileEntity = httpResponse.getEntity();

        if (fileEntity != null) {
            FileUtils.copyInputStreamToFile(fileEntity.getContent(), new File(fileSavePath));
        }

    } catch (IOException e) {
        isSucceed = false;
    }

    httpGet.releaseConnection();

    return isSucceed;
}

Contrairement à la seule ligne de code:

FileUtils.copyURLToFile(fileURL, new File(fileSavePath),
                        URLS_FETCH_TIMEOUT, URLS_FETCH_TIMEOUT);

Ce code vous donnera plus de contrôle sur un processus et vous permettra de spécifier non seulement les délais mais User-Agent et Referer valeurs, qui sont critiques pour de nombreux sites Web.

 2
Author: Mike B., 2016-03-19 16:59:14

Il y a beaucoup de réponses élégantes et efficaces ici. Mais la concision peut nous faire perdre quelques informations utiles. En particulier, on ne veut souvent pas considérer une erreur de connexion comme une exception, et on peut vouloir traiter différemment certaines erreurs liées au réseau-par exemple, pour décider si nous devons réessayer le téléchargement.

Voici une méthode qui ne lève pas d'exceptions pour les erreurs réseau (uniquement pour des problèmes vraiment exceptionnels, comme une url mal formée ou des problèmes écrire dans le fichier)

/**
 * Downloads from a (http/https) URL and saves to a file. 
 * Does not consider a connection error an Exception. Instead it returns:
 *  
 *    0=ok  
 *    1=connection interrupted, timeout (but something was read)
 *    2=not found (FileNotFoundException) (404) 
 *    3=server error (500...) 
 *    4=could not connect: connection timeout (no internet?) java.net.SocketTimeoutException
 *    5=could not connect: (server down?) java.net.ConnectException
 *    6=could not resolve host (bad host, or no internet - no dns)
 * 
 * @param file File to write. Parent directory will be created if necessary
 * @param url  http/https url to connect
 * @param secsConnectTimeout Seconds to wait for connection establishment
 * @param secsReadTimeout Read timeout in seconds - trasmission will abort if it freezes more than this 
 * @return See above
 * @throws IOException Only if URL is malformed or if could not create the file
 */
public static int saveUrl(final Path file, final URL url, 
  int secsConnectTimeout, int secsReadTimeout) throws IOException {
    Files.createDirectories(file.getParent()); // make sure parent dir exists , this can throw exception
    URLConnection conn = url.openConnection(); // can throw exception if bad url
    if( secsConnectTimeout > 0 ) conn.setConnectTimeout(secsConnectTimeout * 1000);
    if( secsReadTimeout > 0 ) conn.setReadTimeout(secsReadTimeout * 1000);
    int ret = 0;
    boolean somethingRead = false;
    try (InputStream is = conn.getInputStream()) {
        try (BufferedInputStream in = new BufferedInputStream(is); OutputStream fout = Files
                .newOutputStream(file)) {
            final byte data[] = new byte[8192];
            int count;
            while((count = in.read(data)) > 0) {
                somethingRead = true;
                fout.write(data, 0, count);
            }
        }
    } catch(java.io.IOException e) { 
        int httpcode = 999;
        try {
            httpcode = ((HttpURLConnection) conn).getResponseCode();
        } catch(Exception ee) {}
        if( somethingRead && e instanceof java.net.SocketTimeoutException ) ret = 1;
        else if( e instanceof FileNotFoundException && httpcode >= 400 && httpcode < 500 ) ret = 2; 
        else if( httpcode >= 400 && httpcode < 600 ) ret = 3; 
        else if( e instanceof java.net.SocketTimeoutException ) ret = 4; 
        else if( e instanceof java.net.ConnectException ) ret = 5; 
        else if( e instanceof java.net.UnknownHostException ) ret = 6;  
        else throw e;
    }
    return ret;
}
 2
Author: leonbloy, 2017-05-21 01:43:37

Ci-dessous est l'exemple de code pour télécharger le film à partir d'Internet avec le code java:

URL url = new 
URL("http://103.66.178.220/ftp/HDD2/Hindi%20Movies/2018/Hichki%202018.mkv");
    BufferedInputStream bufferedInputStream = new  BufferedInputStream(url.openStream());
    FileOutputStream stream = new FileOutputStream("/home/sachin/Desktop/test.mkv");


    int count=0;
    byte[] b1 = new byte[100];

    while((count = bufferedInputStream.read(b1)) != -1) {
        System.out.println("b1:"+b1+">>"+count+ ">> KB downloaded:"+new File("/home/sachin/Desktop/test.mkv").length()/1024);
        stream.write(b1, 0, count);
    }
 2
Author: Sachin Rane, 2018-05-27 11:04:04

Il y a un problème avec l'utilisation simple de:

org.apache.commons.io.FileUtils.copyURLToFile(URL, File) 

Si vous avez besoin de télécharger et d'enregistrer des fichiers très volumineux, ou en général si vous avez besoin de nouvelles tentatives automatiques en cas de perte de connexion.

Ce que je suggère dans de tels cas, c'est Apache HttpClient avec org. apache. commons.io. FileUtils. Par exemple:

GetMethod method = new GetMethod(resource_url);
try {
    int statusCode = client.executeMethod(method);
    if (statusCode != HttpStatus.SC_OK) {
        logger.error("Get method failed: " + method.getStatusLine());
    }       
    org.apache.commons.io.FileUtils.copyInputStreamToFile(
        method.getResponseBodyAsStream(), new File(resource_file));
    } catch (HttpException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
    method.releaseConnection();
}
 1
Author: oktieh, 2014-08-19 21:25:10

Pour résumer (et en quelque sorte polir et mettre à jour) les réponses précédentes. Les trois méthodes suivantes sont pratiquement équivalentes. (J'ai ajouté des délais d'attente explicites parce que je pense qu'ils sont indispensables, personne ne veut qu'un téléchargement se fige pour toujours lorsque la connexion est perdue.)

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();
}

Je ne trouve pas de différences significatives, toutes me semblent correctes. Ils sont sûrs et efficaces. (Les différences de vitesse ne semblent guère pertinentes - j'écris 180 Mo du serveur local sur un disque SSD dans des périodes qui fluctuent autour de 1,2 à 1,5 segs). Ils ne nécessitent pas de bibliothèques externes. Tous fonctionnent avec des tailles arbitraires et (selon mon expérience) des redirections HTTP.

De plus, tous lancent FileNotFoundException si la ressource n'est pas trouvée (erreur 404, généralement), et java.net.UnknownHostException si la résolution DNS a échoué; d'autres IOException correspondent à des erreurs lors de la transmission.

(Marqué comme wiki communautaire, n'hésitez pas à ajouter des informations ou des corrections)

 1
Author: leonbloy, 2017-05-21 01:19:09

Il existe une méthode U. fetch(URL) dans la bibliothèque underscore-java.

Pom.xml:

  <groupId>com.github.javadev</groupId>
  <artifactId>underscore</artifactId>
  <version>1.45</version>

Exemple de code:

import com.github.underscore.lodash.U;

public class Download {
    public static void main(String ... args) {
        String text = U.fetch("https://stackoverflow.com/questions"
        + "/921262/how-to-download-and-save-a-file-from-internet-using-java").text();
    }
}
 1
Author: Valentyn Kolesnikov, 2019-06-09 18:54:29
public class DownloadManager {

    static String urls = "[WEBSITE NAME]";

    public static void main(String[] args) throws IOException{
        URL url = verify(urls);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        InputStream in = null;
        String filename = url.getFile();
        filename = filename.substring(filename.lastIndexOf('/') + 1);
        FileOutputStream out = new FileOutputStream("C:\\Java2_programiranje/Network/DownloadTest1/Project/Output" + File.separator + filename);
        in = connection.getInputStream();
        int read = -1;
        byte[] buffer = new byte[4096];
        while((read = in.read(buffer)) != -1){
            out.write(buffer, 0, read);
            System.out.println("[SYSTEM/INFO]: Downloading file...");
        }
        in.close();
        out.close();
        System.out.println("[SYSTEM/INFO]: File Downloaded!");
    }
    private static URL verify(String url){
        if(!url.toLowerCase().startsWith("http://")) {
            return null;
        }
        URL verifyUrl = null;

        try{
            verifyUrl = new URL(url);
        }catch(Exception e){
            e.printStackTrace();
        }
        return verifyUrl;
    }
}
 0
Author: Gegi4321, 2017-07-02 02:03:08

Vous pouvez le faire en 1 ligne en utilisant netloader pour Java:

new NetFile(new File("my/zips/1.zip"), "https://example.com/example.zip", -1).load(); //returns true if succeed, otherwise false.
 0
Author: Celestine, 2017-07-12 20:25:02

Si vous êtes derrière un proxy, vous pouvez définir les proxys dans le programme java comme ci-dessous:

        Properties systemSettings = System.getProperties();
        systemSettings.put("proxySet", "true");
        systemSettings.put("https.proxyHost", "https proxy of your org");
        systemSettings.put("https.proxyPort", "8080");

Si vous n'êtes pas derrière un proxy, n'incluez pas les lignes ci-dessus dans votre code. Code de travail complet pour télécharger un fichier lorsque vous êtes derrière un proxy.

public static void main(String[] args) throws IOException {
        String url="https://raw.githubusercontent.com/bpjoshi/fxservice/master/src/test/java/com/bpjoshi/fxservice/api/TradeControllerTest.java";
        OutputStream outStream=null;
        URLConnection connection=null;
        InputStream is=null;
        File targetFile=null;
        URL server=null;
        //Setting up proxies
        Properties systemSettings = System.getProperties();
            systemSettings.put("proxySet", "true");
            systemSettings.put("https.proxyHost", "https proxy of my organisation");
            systemSettings.put("https.proxyPort", "8080");
            //The same way we could also set proxy for http
            System.setProperty("java.net.useSystemProxies", "true");
            //code to fetch file
        try {
            server=new URL(url);
            connection = server.openConnection();
            is = connection.getInputStream();
            byte[] buffer = new byte[is.available()];
            is.read(buffer);

                targetFile = new File("src/main/resources/targetFile.java");
                outStream = new FileOutputStream(targetFile);
                outStream.write(buffer);
        } catch (MalformedURLException e) {
            System.out.println("THE URL IS NOT CORRECT ");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("Io exception");
            e.printStackTrace();
        }
        finally{
            if(outStream!=null) outStream.close();
        }
    }
 0
Author: bpjoshi, 2017-11-16 11:36:51

1ère méthode utilisant le nouveau canal

ReadableByteChannel aq = Channels.newChannel(new url("https//asd/abc.txt").openStream());
FileOutputStream fileOS = new FileOutputStream("C:Users/local/abc.txt")
FileChannel writech = fileOS.getChannel();

2ème méthode utilisant FileUtils

FileUtils.copyURLToFile(new url("https//asd/abc.txt",new local file on system("C":/Users/system/abc.txt"));

3ème méthode utilisant

InputStream xy = new ("https//asd/abc.txt").openStream();

Voici comment nous pouvons télécharger le fichier en utilisant le code java de base et d'autres bibliothèques tierces. Ce sont juste pour la référence rapide. Veuillez google avec les mots clés ci-dessus pour obtenir des informations détaillées et d'autres options.

 0
Author: Ashish Gupta, 2020-05-31 08:41:39

Cela peut lire un fichier sur Internet et l'écrire dans un fichier.J'espère que cette également utile pour vous.

import java.net.URL;
import java.io.FileOutputStream;
import java.io.File;

public class Download {
    public static void main(String[] args) throws Exception {
         URL url = new URL("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");  // Input Url
         FileOutputStream out = new FileOutputStream(new File("out.png"));         // Output File
         out.write(url.openStream().readAllBytes());
         out.close();
    }
}
 0
Author: Suchin Madusha, 2021-01-28 09:59:56