java文件下载断点续传,java文件传输断点续传
Java多线程下载可以明显提高下载速度。通常我们使用的迅雷软件之所以能下载这么快,就是因为它使用了多线程。用户在下载过程中,有断电或断网的可能。当用户再次点击下载时,应该允许用户按照原来的进度下载,这样可以节省用户的流量,所以要使用断点续传的功能。下面是通过Java代码实现多线程下载和断点续传的详细代码。
1.创建一个下载文件的类。
包com . edu . thread;导入Java . io . buffered reader;导入Java . io . file;导入Java . io . file inputstream;导入Java . io . inputstream;导入Java . io . inputstreamreader;导入Java . io . random access file;导入Java . net . httpurl connection;导入Java . net . URL;public class multi download 2 { static String path= http://localhost :8080/WLAN . zip ;//打开线程数static int thread count=6;//下载结束时的线程数static int thread finished=0;public static void main(String[]args){ try { URL URL=new URL(path);HttpURLConnection conn=(http urlconnection)URL . open connection();conn . setrequestmethod( GET );conn . setconnecttimeout(5000);conn . setreadtime out(5000);//此时只确认与服务器的连接已经建立,但是任务if (conn.getresponsecode ()==200)还没有开始下载{//获取文件长度int length=conn . Get contentlength();//指定文件路径和文件名File File=new File( d ://File test ,get filename(path));//创建随机存储文件大小,以建立一个与源文件大小相同的存储区间随机访问文件RAF=new random access file (file, RWD );//设置临时文件的大小,与服务器文件raf.setLength(长度)完全相同;//计算每个线程下载的字节数int size=length/thread count;//计算三个线程下载的起始位置和结束位置(int I=0;我threadCountI){ int startIndex=I * size;int endIndex=(I ^ 1)* size-1;//如果是最后一个线程,从0开始读取end If(I==thread count-1){//length,所以length-1表示最后一个字节endIndex=length-1;}//打印三个线程的开始和结束位置system . out . println( thread I : startindex - end index )的开始和结束位置;//启动线程,传入线程ID,下载开始位置和下载结束位置,newdownloadthread (i,startindex,end index)。start();} } } catch(异常e){ e . printstacktrace();}}/* *获取文件名*/公共静态字符串getfilename(字符串路径){ int index=path . lastindexof(/);返回path.substring(索引1);}}2.创造
建另一个类,用于开启子线程
package com.edu.thread; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;//新开启一个线程,用于完成下载任务class DownloadThread extends Thread{ int thredId; int startIndex; int endIndex; public DownloadThread(int thredId, int startIndex, int endIndex) { super(); this.thredId = thredId; this.startIndex = startIndex; this.endIndex = endIndex; } public void run() { try { //下载进度文件保存的路径和文件名 File progressFile = new File("d://文件测试",(thredId + ".txt")); //判断保存下载进度的临时文件是否存在,以便确定下载的开始位置 if (progressFile.exists()) { FileInputStream fis = new FileInputStream(progressFile); BufferedReader bReader = new BufferedReader(new InputStreamReader(fis)); //拿到临时文件中保存的数据,并把此数据设置为新的开始位置 int text = Integer.parseInt(bReader.readLine()); startIndex = text; fis.close(); } System.out.println("线程"+thredId+"的最终开始下载位置是:"+startIndex); URL url = new URL(MultiDownload2.path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); //设置请求数据的范围 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); //建立连接,状态码206表示请求部分数据成功,此时开始下载任务 if (conn.getResponseCode()==206) { InputStream is = conn.getInputStream(); //指定文件名和文件路径 File file = new File(MultiDownload2.getFileName(MultiDownload2.path) ); int len = 0; byte [] b = new byte[1024]; //三个线程各自创建自己的随机存储文件 RandomAccessFile raf = new RandomAccessFile(file, "rwd"); //设置数据从哪个位置开始写入数据到临时文件 raf.seek(startIndex); //设置当前线程下载的总字节数 int total = 0; long start = System.currentTimeMillis(); //当下载意外停止时,记录当前下载进度 int currentPosition = startIndex; while ((len=is.read(b))!=-1) { raf.write(b,0,len); //打印当前线程下载的总字节数 total += len; /** * 实现断点续传的功能 */ //RandomAccessFile主要用来存放下载的临时文件,可以用FileOutputStream代替 RandomAccessFile rafProgress = new RandomAccessFile(progressFile, "rwd"); //再次下载时的开始位置 currentPosition = startIndex + total; //把下载进度写进rafProgress临时文件,下一次下载时,就以这个值作为新的startIndex rafProgress.write((currentPosition + "").getBytes()); //关流 rafProgress.close(); System.out.println("线程"+thredId+"已经下载了"+total); } raf.close(); long end = System.currentTimeMillis(); //打印线程下载文件用时 System.out.println("线程"+thredId+"下载文件用时"+(end-start)+"ms"); //打印线程的结束 System.out.println("线程:"+thredId+" 下载结束了 !!!"); //下载结束后,删除所有的临时文件 MultiDownload2.threadFinished ++; //使用同步语句块,保证线程的安全性 synchronized (MultiDownload2.path) { //如果这个条件成立,说明所有的线程下载结束 if (MultiDownload2.threadFinished == MultiDownload2.threadCount) { for (int i = 0; i < MultiDownload2.threadCount; i++) { //删除三个线程产生的临时文件 File temp = new File("d://文件测试", i + ".txt"); temp.delete(); } //保证三个线程的临时文件同时被删除 MultiDownload2.threadFinished = 0; } } } } catch (Exception e) { e.printStackTrace(); } }}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持盛行IT。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。