Telecharger un fichier a partir d'une url en specifiant un nombre de connexion

Contenu du snippet

Un code pour télécharger un fichier depuis une URL spécifiée.

Vous pouvez spécifier le nombre de connexion pour une URL.

Pour comprendre le code il faudrait que vous ayez un savoir de :
Java IO
Java Nio
Multi-Threading
et un petit savoir dans les Design Pattern ( je cite Observer/Observable et Singleton )

Source / Exemple :


package ma.hossame.naji.downloader;

/**

  • @author hossame
  • /
public class FileSingleton { private static FileSingleton instance = null; private long size = -1; private int connectionNumber = -1; private FileSingleton() { } public long getSize() { return size; } public void setSize(long size) { this.size = size; } public int getConnectionNumber() { return connectionNumber; } public void setConnectionNumber(int connectionNumber) { this.connectionNumber = connectionNumber; } public long[] calculatePartSize() { System.out.println("File size = "+size); long[] partSizes = new long[connectionNumber]; long chunk = size / (connectionNumber - 1) ; for(int i = 0; i < connectionNumber - 1 ; i++) { partSizes[i] = chunk; } if(size % (connectionNumber - 1) != 0) { partSizes[connectionNumber - 1 ] = size % (connectionNumber - 1) ; } else { partSizes[connectionNumber - 1] = chunk ; } for(long l : partSizes){ System.out.println("Part Sizes => "+l); } return partSizes; } public static FileSingleton getInstance() { if(instance == null) { instance = new FileSingleton(); } return instance; } } ######################## package ma.hossame.naji.downloader; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import java.util.Observable; import java.util.Observer; /** *
  • @author hossame
  • /
public class ConnectionSizeCalculator implements Observer { private FileSingleton valueHolder = FileSingleton.getInstance();; public ConnectionSizeCalculator() { } private int tryGetFileSize(HttpURLConnection conn) { try { conn.setRequestMethod("GET"); conn.getInputStream(); return conn.getContentLength(); } catch (IOException e) { return -1; } } @Override public void update(Observable o, Object arg) { if(o instanceof ChunckDownloader) { HttpURLConnection urlc = (HttpURLConnection)((Map<String,Object>)arg).get("connection"); int fileSize = -1; if(valueHolder.getSize() == -1 ) { fileSize = tryGetFileSize(urlc); valueHolder.setSize(fileSize); } } } } ################################# package ma.hossame.naji.downloader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.HashMap; import java.util.Map; import java.util.Observable; import java.util.concurrent.Callable; /** *
  • @author hossame
  • /
public class ChunckDownloader extends Observable implements Callable<Boolean> { private URL url; private String fileName; private File directory; private int id; private FileSingleton valueHolder; private URLConnection urlc; private File temp; public ChunckDownloader(int id, URL url, String fileName, File directory) { this.url = url; this.fileName = fileName; this.directory = directory; this.id = id; valueHolder = FileSingleton.getInstance(); try { createTemporaryFile(); } catch (IOException ex) { System.out.println(ex.getMessage()); } ConnectionSizeCalculator csc = new ConnectionSizeCalculator(); this.addObserver(csc); this.setChanged(); } private void openConnection() throws IOException { urlc = this.url.openConnection(); Map<String,Object> props = new HashMap<String,Object>(); props.put("id", id); props.put("connection", urlc); super.notifyObservers(props); super.setChanged(); } private void createTemporaryFile() throws IOException { temp = File.createTempFile(fileName, ".part"+id, directory); } public File getDirectory() { return directory; } public int getId() { return id; } public File getTemp() { return temp; } private void download() throws FileNotFoundException, IOException { FileOutputStream fos = new FileOutputStream(temp); WritableByteChannel wbc = Channels.newChannel(fos); InputStream is = urlc.getInputStream(); long[] calculatePartSize = valueHolder.calculatePartSize(); long skip = -1L; if(valueHolder.getConnectionNumber() > 1) { if(id < valueHolder.getConnectionNumber()) { skip = is.skip(id * calculatePartSize[0]); } else { skip = is.skip((id - 1) * calculatePartSize[0] + calculatePartSize[id - 1]); } } else if(valueHolder.getConnectionNumber() == 1) { } else { return ; } ReadableByteChannel rbc = Channels.newChannel(is); ByteBuffer buffer = null; long count = calculatePartSize[id] ; while(count>0) { if(count>128) { buffer = ByteBuffer.allocate(128); count-=128; } else { buffer = ByteBuffer.allocate((int)count); count=0; } rbc.read(buffer); buffer.flip(); wbc.write(buffer); buffer.clear(); } rbc.close(); wbc.close(); fos.close(); is.close(); } @Override public Boolean call() throws Exception { try { openConnection(); download(); } catch (IOException ex) { System.out.println(ex.getMessage()); } return true; } } ################################# package ma.hossame.naji.downloader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.logging.Level; import java.util.logging.Logger; /** *
  • @author hossame
  • /
public class ConnectionOpener { private int numberOfConnections; private FileSingleton valueHolder; private List<ChunckDownloader> downloaders; private ExecutorService es; private List<File> fileList; private File directory; private String fileName; public ConnectionOpener(URL url, int numberOfConnections, String fileName, File directory) { this.directory = directory; this.fileName = fileName; valueHolder = FileSingleton.getInstance(); this.numberOfConnections = numberOfConnections; valueHolder.setConnectionNumber(numberOfConnections); this.downloaders = new ArrayList<ChunckDownloader>(); ChunckDownloader downloader = null ; fileList = new ArrayList<File>(); for(int i = 0; i<numberOfConnections; i++){ downloader = new ChunckDownloader(i, url, fileName, directory); downloaders.add(downloader); fileList.add(i, downloader.getTemp()); } } private static boolean isAllTrue(List<Boolean> list) { boolean flag = true; for(Boolean e : list) { flag &= e; } return flag; } public void download() { es = Executors.newFixedThreadPool(numberOfConnections); List<Boolean> futurs = new ArrayList<Boolean>(); ChunckDownloader d = null; for(int i = 0; i < downloaders.size(); i++) { d = downloaders.get(i); try { futurs.add(es.submit(d).get()); } catch (InterruptedException ex) { System.out.println(ex.getMessage()); } catch (ExecutionException ex) { System.out.println(ex.getMessage()); } } System.out.println(futurs); while(!(futurs.size() == downloaders.size() && isAllTrue(futurs))) { try { Thread.sleep(500); System.out.println("Sleep"); } catch (InterruptedException ex) { System.out.println(ex.getMessage()); } } es.shutdown(); File f = new File(directory.getAbsolutePath()+"/"+fileName); try { f.createNewFile(); FileOutputStream fos = new FileOutputStream(f); WritableByteChannel wbc = Channels.newChannel(fos); FileInputStream fis = null; ByteBuffer bb = null; for(int i = 0 ; i < fileList.size(); i++ ) { fis = new FileInputStream(fileList.get(i)); ReadableByteChannel rbc = Channels.newChannel(fis); long length = fileList.get(i).length(); while(length>0) { if(length>=4096) { bb = ByteBuffer.allocate(4096); length-=4096; } else { bb = ByteBuffer.allocate((int)length); length=0; } rbc.read(bb); bb.flip(); wbc.write(bb); bb.clear(); } fis.close(); rbc.close(); fileList.get(i).delete(); } wbc.close(); fos.close(); } catch (IOException ex) { } } public static void main(String[] args) throws MalformedURLException { URL url = new URL("http://localhost/Desktop.zip"); String fileName = "Desktop.zip"; File directory = new File("/home/hossame/Desktop/dowloader"); int numberOfConnections = 4; ConnectionOpener co = new ConnectionOpener(url, numberOfConnections, fileName, directory); co.download(); } }

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.