昨天我们小组进行了任务的进一步划分,我要完成客户端和浏览器之间的数据传输部分,而这和前台的接口需要我和同伴协商后完成。昨天我练习了是用多线程断点下载技术,作为我们的客户端和服务器之间的数据连接工具。在电脑上运行我写的程序是没有问题了,但是移植到android系统上就会错误,目前还没有找到问题所在,系统提示说是权限被拒绝,但是我明明在清单文件中加了相应的权限的啊。今天我需要找到这个问题,并解决它。昨天写的程序还是有一些缺陷,比如说下载过程中不能得到文件下载的进度,所以今天我还要改进这个程序。
我的程序代码:
1 public static int threadCount = 3; 2 public static long blockSize; 3 public static int runingThreadCount; 4 private static int status; 5 6 /** 7 * @param res 资源路径 8 * @param file 下载后的文件存放位置(路径名+加文件名) 9 * @return 下载是否成功 10 */ 11 public static int download(String res,String file){ 12 13 final String path = res,filename = file; 14 new Thread(){ 15 public void run() { 16 int length = 0; 17 HttpURLConnection con = null; 18 try { 19 //设置连接相关的参数 20 con = (HttpURLConnection) new URL(path).openConnection(); 21 con.setRequestMethod("GET"); 22 con.setConnectTimeout(10000); 23 con.setReadTimeout(5000); 24 con.connect(); 25 26 if (con.getResponseCode()==200) { 27 System.out.println("DownloadUtils new Thread HttpURLConnection 连接成功!"); 28 //得到服务器文件的大小 29 length = con.getContentLength(); 30 //建立一个空白文件 31 File f = new File(filename); 32 RandomAccessFile raf = new RandomAccessFile(f, "rw"); 33 //设置文件的大小 34 raf.setLength(length); 35 raf.close(); 36 //计算每个线程应当下载的文件的大小 37 blockSize = length / threadCount; 38 //开启子线程下载文件 39 runingThreadCount = threadCount; 40 for (int i = 0; i < threadCount; i++) { 41 long startIndex = i * blockSize; 42 long endIndex = (i + 1) * blockSize - 1; 43 if (i == threadCount - 1) 44 endIndex = length; 45 System.out.println("开启子线程 "+(i+1)+" 下载位置 "+startIndex+" - "+endIndex); 46 new DownloadThread((i+1),path, startIndex, endIndex, f).start(); 47 } 48 }else{ 49 System.out.println("DownloadUtils new Thread HttpURLConnection 连接失败!"); 50 } 51 } catch (Exception e) { 52 // TODO Auto-generated catch block 53 e.printStackTrace(); 54 } finally { 55 if(con != null) 56 con.disconnect(); 57 } 58 59 }; 60 }.start(); 61 62 return status; 63 } 64 65 private static class DownloadThread extends Thread{ 66 private int threadId; 67 private long startIndex,endIndex; //下载开始点和结束点 68 private String path; //下载路径 69 private File file; //文件存放路径和文件名 70 public DownloadThread(int id,String path,long startIndex,long endIndex,File file){ 71 this.startIndex = startIndex; 72 this.endIndex = endIndex; 73 this.path = path; 74 this.file = file; 75 threadId = id; 76 } 77 78 @Override 79 public void run() { 80 // TODO Auto-generated method stub 81 super.run(); 82 HttpURLConnection con = null; 83 84 // 从文件中读出上次下载的位置,此次应当接着上次的位置开始下载 85 long tatol = 0; 86 try{ 87 BufferedReader read = new BufferedReader(new FileReader(threadId+".txt")); 88 String s = null; 89 while((s = read.readLine())!=null){ 90 tatol = Long.parseLong(s); 91 } 92 System.out.println("子线程"+threadId+"上次下载文件总大小:"+tatol); 93 startIndex += tatol; 94 System.out.println("子线程"+threadId+"本次下载位置:"+startIndex+" - "+endIndex); 95 read.close(); 96 }catch(Exception e){} 97 try { 98 //设置连接的参数 99 con = (HttpURLConnection) new URL(path).openConnection(); 100 con.setRequestMethod("GET"); 101 con.setConnectTimeout(10000); 102 //设置请求头,这个请求头必须设置 103 con.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); 104 105 //得到服务器的响应码 106 int code = con.getResponseCode(); 107 if(code / 100 == 2){ 108 System.out.println("线程"+threadId+"连接成功,下载开始!"+"响应码:"+code); 109 //建立自由读写文件流 110 RandomAccessFile raf = new RandomAccessFile(file,"rw"); 111 112 113 //将读写指针移动到本线程下载资源的首位置 114 raf.seek(startIndex); 115 InputStream is = con.getInputStream(); 116 PrintStream out = new PrintStream(new FileOutputStream(threadId+".txt",true)); 117 int len = 0; 118 byte[] buffer = new byte[1024*1024]; 119 //开始读写 120 System.out.println("子线程"+threadId+"读写文件开始!"); 121 while((len = is.read(buffer))!=-1){ 122 raf.write(buffer,0,len); 123 tatol += len; 124 out.println(tatol); 125 } 126 out.close(); 127 is.close(); 128 raf.close(); 129 System.out.println("线程"+threadId+"下载成功!"); 130 }else{ 131 System.out.println("线程"+threadId+"连接失败!"+"响应码:"+code); 132 } 133 } catch (Exception e) { 134 // TODO Auto-generated catch block 135 e.printStackTrace(); 136 System.out.println("线程"+threadId+"下载异常!"); 137 }finally{ 138 if(con!=null) 139 con.disconnect(); 140 synchronized (DownloadUtils.class) { 141 runingThreadCount--; 142 if (runingThreadCount < 1) { 143 System.out.println("所有线程都下载完毕,删除临时记录文件!"); 144 for (int i = 1; i <= threadCount; i++) { 145 File f = new File(i + ".txt"); 146 System.out.println("临时记录文件文件 ‘" + i + ".txt’删除 " + f.delete()); 147 } 148 } 149 } 150 } 151 } 152 }