网络多线线程下载并合并文件示例
2017-11-08 11:23
225 查看
本示例的采用IO流与多线程下载同一张图片,下载完后进行合并;使用方法内创建线程方式,控制主线程的执行时机,即主线程调用方法,方法内创建线程,再返回调用方法的对象,随即往下执行其他程序,可有效防止主线程的其他方法在下载线程(即其他线程)未完成时执行,而出现数据错位缺失。
1 import java.io.*; 2 import java.net.URL; 3 import java.net.URLConnection; 4 5 /** 6 * Created by gdkong on 07/11/2017. 7 */ 8 9 public class Test { 10 11 public static void main(String[] args) throws IOException, InterruptedException { 12 //主线程采用调用方法模式创建其他线程,可让其他线程执行完后才继续执行主线中的其他方法,此方式可控制主线的执行时机 13 multithreadedDownload ("http://localhost:8080/image/a.jpg","/Users/Shared/abc",3); 14 } 15 16 /** 17 * 多线程下载并合并文件,仅适用于Http协议,未尝试其他网络协议 18 * @param srcPath 下载源文件路径名 19 * @param destPath 保存文件夹路径名 20 * @param count 指定线程个数 21 */ 22 public static void multithreadedDownload(String srcPath, String destPath, int count) throws IOException, InterruptedException { 23 24 //定义一个文件下载的文件夹路径 25 File dir = new File (destPath); 26 if (!dir.exists ()) { 27 dir.mkdirs (); 28 } 29 long total = getFileLength (srcPath); 30 //开启下载线程 31 OpenMultithreadedDownload (srcPath, dir, total, count); 32 33 //获取文件的后缀名 34 String suffix = srcPath.substring (srcPath.lastIndexOf (".")); 35 //合并文件 36 FileUtils.merge (dir, suffix); 37 38 System.out.println ("文件下载完成"); 39 } 40 41 /** 42 * 多线程下载块 43 * @param path 下载源文件路径名 44 * @param dir 目标文件存储目录 45 * @param total 下载源文件大小 46 * @param count 指定线程个数 47 */ 48 private static void OpenMultithreadedDownload(String path, File dir, long total, int count) throws InterruptedException { 49 50 //计算出每个线程平均现在的字节个数 51 long size = total / count; 52 //使用循环,计算每个线程下载开始和结束位置 53 for (int i = 1; i <= count; i++) { 54 //开始位置 55 long starIndex = (i - 1) * size; 56 //结束位置 57 long endIndex = i * size - 1; 58 //最后一个线程 59 if (i == 3) { 60 endIndex = total - 1; 61 } 62 DownloadThread dt = new DownloadThread (path, dir, starIndex, endIndex, i); 63 dt.start (); 64 } 65 } 66 67 /** 68 * 获取下载源文件大小 69 * @param path 下载源文件路径名 70 * */ 71 public static long getFileLength(String path) throws IOException { 72 73 URL url = new URL (path); 74 //获得连接对象 75 URLConnection con = url.openConnection (); 76 long total = con.getContentLengthLong (); 77 return total; 78 } 79 /** 80 * 合并文件功能 81 * @param dir 源文件存储的父目录 82 * @param suffix 文件的后缀名,用于过滤文件 83 */ 84 public static void merge(File dir,String suffix) throws IOException { 85 86 File[] files = dir.listFiles (FileUtils.getFileFilter (suffix,false)); 87 FileOutputStream fos = getFileOutputStream (dir, files[0]); 88 89 for(File file : files){ 90 FileInputStream fis = new FileInputStream (file); 91 int len; 92 byte[] buf = new byte[8192]; 93 while ((len=fis.read (buf)) != -1){ 94 fos.write (buf,0,len); 95 } 96 fis.close (); 97 //把已经合并过的文件删除 98 file.delete (); 99 } 100 fos.close (); 101 } 102 //获取合并文件输出流 103 private static FileOutputStream getFileOutputStream(File dir, File file) throws FileNotFoundException { 104 File file1 = file; 105 String name = file1.getName (); 106 name = name.substring (1); 107 File destFile = new File (dir,name); 108 return new FileOutputStream (destFile); 109 } 110 /** 111 * 文件过滤器 112 * @param suffix 文件后缀名 113 * @param containDirectory 是否显示子文件夹文件,true为显示,false不显示 114 */ 115 public static FileFilter getFileFilter(String suffix,boolean containDirectory) { 116 return new FileFilter () { 117 @Override 118 public boolean accept(File file) { 119 String name = file.getName (); 120 boolean destFormat = file.isFile()&& name.endsWith(suffix); 121 boolean b; 122 123 b = containDirectory && file.isDirectory (); 124 125 if (destFormat || b) return true; 126 else return false; 127 } 128 }; 129 } 130 } 131 132 //下载线程代码 133 class DownloadThread extends Thread { 134 135 private final String path; 136 private final File dir; 137 private final long startIndex; 138 private final long endIndex; 139 private final int threadID; 140 //使用构造方法传入参数 141 public DownloadThread(String path, File dir, long startIndex, 142 long endIndex, int threadID) { 143 this.path = path; 144 this.dir = dir; 145 this.startIndex = startIndex; 146 this.endIndex = endIndex; 147 this.threadID = threadID; 148 } 149 @Override 150 public void run() { 151 try { 152 InputStream in = getInputStream (); 153 FileOutputStream fos = getFileOutputStream (); 154 int len ; 155 byte[] arr = new byte[8192]; 156 while ((len = in.read (arr)) != -1){ 157 fos.write (arr,0,len); 158 } 159 in.close (); 160 fos.close (); 161 } catch (Exception e) { 162 e.printStackTrace (); 163 } 164 165 } 166 //获取下载输出流 167 private FileOutputStream getFileOutputStream() throws FileNotFoundException { 168 //获取到文件的名字 169 int index = path.lastIndexOf ("/")+1; 170 String name = path.substring (index); 171 File file = new File (dir,threadID+name);//创建目标文件键,防止文件覆盖 172 //创建一个输出流 173 return new FileOutputStream (file); 174 } 175 //获取下载的输入流 176 private InputStream getInputStream() throws IOException { 177 //创建一个URL对象 178 URL url= new URL (path); 179 //获取到连接对象 180 URLConnection con = url.openConnection (); 181 con.setRequestProperty ("Range","bytes="+startIndex+"-"+endIndex); 182 //获取到输入流 183 return con.getInputStream (); 184 } 185 }
相关文章推荐
- 网络多线线程下载并合并文件示例
- java高级---线程、网络、文件、流、序列化等代码示例
- Java网络编程之单线程下载文件设置显示进度(一)
- Java网络编程之单线程下载文件设置显示进度
- Java实现网络文件下载的简单示例
- 网络加速手段之一,JS文件资源合并下载
- Java用文件流下载网络文件示例代码
- 网络加速手段之一,JS文件资源合并下载
- Android下载文件的进度条提示(网络通信部分示例)
- Python使用wget实现下载网络文件功能示例
- Java网络编程之单线程下载文件---多线程下载单个文件
- 【转】Asp.net 2.0 文件下载[支持多线程, 断点续传功能](示例代码下载)
- JDK中http协议下载文件简单示例
- Control Study->AdRotator广告控件显示自定义配置文件中广告以及与DataGrid控件结合使用显示图片(示例代码下载)
- Android 从网络上下载文件以及写入到SDcard里面
- 利用JAVA下载网络文件
- java中Struts2 的文件上传和下载示例
- 网络编程练习 -- 大文件下载
- 网络:文件下载
- 网络:ASI 框架使用(上传与下载文件)