RandomAccessFile类:

此类的实例支持对随机訪问文件的读取和写入。随机訪问文件的行为相似存储在文件系统中的一个大型 byte 数组。

存在指向该隐含数组。光标或索引,称为文件指针。输入操作从文件指针開始读取字节。并随着对字节的读取而前移此文件指针。

假设随机訪问文件以读取/写入模式创建,则输出操作也可用。输出操作从文件指针開始写入字节。并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针能够通过 getFilePointer 方法读取。并通过 seek 方法设置。

以下有RandomAccessFile实现安卓下的断点下载的demo。

server端能够用tomcat模拟。将被下载的測试文件放入webApp/ROOT文件夹下就可以。

先给出java借助HttpURLConnection类实现的多线程下载代码:

public class MultiThread {
private static int threadCount = 3;
private static long blockSize;
private static int runningThreadCount;
public static void main(String[] args) throws Exception {
String path = "http://10.0.67.172/test.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);//超时时间
int code = conn.getResponseCode();
System.out.println(code); if(code / 100 == 2){
int size = conn.getContentLength();//获取资源文件的长度
System.out.println("请求资源大小:" + size);
blockSize = size / threadCount;//将资源文件分为多少块。没一块的大小 runningThreadCount = threadCount;
long startIndex = 0;
long endIndex = 0;
//开启若干个子线程去实现多线程的下载
for(int i = 0; i < threadCount; i++){
startIndex = i * blockSize;
endIndex = (i + 1) * blockSize - 1;
if(i == threadCount-1){
endIndex = size - 1;
}
System.out.println("开启线程:" + i + ";" + "開始位置:" + startIndex + ":" + "结束位置:" + endIndex);
new DownThread(path, startIndex, endIndex, i).start();
}
}
} private static class DownThread extends Thread{
private String path;
private long startIndex;
private long endIndex;
private int threadId; public DownThread(String path, long startIndex, long endIndex, int threadId) {
super();
this.path = path;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
} @Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//设置server上的文件的读取位置 int code = conn.getResponseCode();
if(code / 100 == 2){
InputStream is = conn.getInputStream();
File file = new File("temp.exe");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(startIndex);
System.out.println("第" + threadId + "个文件的開始位置:" + String.valueOf(startIndex));
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1){
raf.write(buffer, 0, len);//写文件
}
raf.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

断点下载的原理就是将上次文件下载的位置保存为暂时文件,当全然完成下载时再删除。

public class MultiThread {
private static int threadCount = 3;
private static long blockSize;
private static int runningThreadCount;
public static void main(String[] args) throws Exception {
String path = "http://10.0.67.172/test.rar";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);//超时时间
int code = conn.getResponseCode();
System.out.println(code); if(code / 100 == 2){
int size = conn.getContentLength();//获取资源文件的长度
System.out.println("请求资源大小:" + size);
blockSize = size / threadCount;//将资源文件分为多少块,没一块的大小 runningThreadCount = threadCount;
long startIndex = 0;
long endIndex = 0;
for(int i = 0; i < threadCount; i++){
startIndex = i * blockSize;
endIndex = (i + 1) * blockSize - 1;
if(i == threadCount-1){
endIndex = size - 1;
}
System.out.println("开启线程:" + i + ";" + "開始位置:" + startIndex + ":" + "结束位置:" + endIndex);
new DownThread(path, startIndex, endIndex, i).start();
}
}
} private static class DownThread extends Thread{
private String path;
private long startIndex;
private long endIndex;
private int threadId; public DownThread(String path, long startIndex, long endIndex, int threadId) {
super();
this.path = path;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.threadId = threadId;
} @Override
public void run() {
int total = 0;
try {
File positionFile = new File(threadId + ".txt"); URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//接着上次的文件继续下载
if(positionFile.exists() && positionFile.length() > 0){
FileInputStream fis = new FileInputStream(positionFile);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
//获取当前线程上次下载的总大小是多少
String lasttotalstr = reader.readLine();
int lastTotal = Integer.valueOf(lasttotalstr);
System.out.println("上次线程下载的总大小:" + lastTotal);
startIndex += lastTotal;
total += lastTotal;
fis.close();
}
conn.setReadTimeout(5000);
conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//设置server上的文件的读取位置 int code = conn.getResponseCode();
if(code / 100 == 2){
InputStream is = conn.getInputStream();
File file = new File("temp.rar");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.seek(startIndex);
System.out.println("第" + threadId + "个文件的開始位置:" + String.valueOf(startIndex));
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1){
RandomAccessFile rf = new RandomAccessFile(positionFile, "rwd");
raf.write(buffer, 0, len);//写文件
total += len;
rf.write(String.valueOf(total).getBytes());
rf.close();
}
is.close();
raf.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
synchronized (DownThread.class) {
System.out.println("线程" + threadId + "完成下载了");
runningThreadCount--;
if (runningThreadCount < 1) {
System.out.println("全部的线程都工作完成了。删除暂时记录的文件");
for (int i = 0; i < threadCount; i++) {
File f = new File(i + ".txt");
System.out.println(f.delete());
}
}
}
}
}
}
}

执行结果截图:

Java之多线程断点下载的实现的更多相关文章

  1. Java实现多线程断点下载(下载过程中可以暂停)

    线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器会对总下载线程进行平均分配. ...

  2. Android(java)学习笔记216:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1.新建一个Android工程: (1)其中我们先实现布局 ...

  3. Android(java)学习笔记159:多线程断点下载的原理(Android实现)

    之前在Android(java)学习笔记215中,我们从JavaSE的角度去实现了多线程断点下载,下面从Android角度实现这个断点下载: 1. 新建一个Android工程: (1)其中我们先实现布 ...

  4. java多线程断点下载原理(代码实例演示)

    原文:http://www.open-open.com/lib/view/open1423214229232.html 其实多线程断点下载原理,很简单的,那么我们就来先了解下,如何实现多线程的断点下载 ...

  5. andoid 多线程断点下载

    本示例介绍在Android平台下通过HTTP协议实现断点续传下载. 我们编写的是Andorid的HTTP协议多线程断点下载应用程序.直接使用单线程下载HTTP文件对我们来说是一件非常简单的事.那么,多 ...

  6. 我的Android进阶之旅------>Android基于HTTP协议的多线程断点下载器的实现

    一.首先写这篇文章之前,要了解实现该Android多线程断点下载器的几个知识点 1.多线程下载的原理,如下图所示 注意:由于Android移动设备和PC机的处理器还是不能相比,所以开辟的子线程建议不要 ...

  7. iOS开发网络篇—大文件的多线程断点下载

    http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时 ...

  8. iOS开发网络请求——大文件的多线程断点下载

    iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...

  9. iOS开发网络篇—大文件的多线程断点下载(转)

    http://www.cnblogs.com/wendingding/p/3947550.html   iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了 ...

随机推荐

  1. 【POJ2482】【线段树】Stars in Your Window

    Description Fleeting time does not blur my memory of you. Can it really be 4 years since I first saw ...

  2. 那些年,我们一起被坑的H5音频

    原文地址:http://weibo.com/p/23041874d6cedd0102vkbr   不要被这么文艺的标题吓到,这里不会跟你讲述中学时期泡妞史,也不会有其它什么现实不该有而小说噼里啪啦不能 ...

  3. MySQL 5.6 for Windows 解压缩版配置安装(转)

    转自:http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行.但是官网给 ...

  4. phpcms源码解析(2)

    1.程序启动逻辑: 首先由文件\index.php调用create_app(),此函数在文件\phpcms\base.php中,它完成初始化应用程序,调用函数load_sys_class并提供参数ap ...

  5. springMVC整合memcached,以注解形式使用

    睡不着,深夜写点博客.闲下来有一个月了,心里多少有点…… 在北京找工作一再受阻,这个时间点也不好找 再接再厉 之前没有用过memcached,没有什么实战经验,看了一些关于memcached的博客,写 ...

  6. CSS让图片垂直居中的几种技巧 三种方法介绍

    在网页设计过程中,有时候会希望图片垂直居中的情况.而且,需要垂直居中的图片的高度也不确定,这就会给页面的布局带来一定的挑战.下面总结了一下,曾经使用过的几种方法来使图片垂直居中,除了第一种方法只限于标 ...

  7. Microsfot SQL Server 2012 日志收缩

    //Microsfot SQL Server 2012 日志收缩 USE DataBaseName;GO ALTER DATABASE DataBaseNameSET RECOVERY SIMPLE; ...

  8. RMQ with Shifts

    uva12299:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_prob ...

  9. GitHub超详细图文攻略 - Git客户端下载安装 GitHub提交修改源码工作流程 Git分支 标签 过滤 Git版本工作流

    最近听同事说他都在使用GitHub,GitHub是程序员的社区,在里面可以学到很多书上学不到的东西,所以最近在准备入手这方面的知识去尝试学习,正好碰到这么详细完整的文章,就转载了,希望对自己和大家有帮 ...

  10. 【HDOJ】2217 Visit

    挺好的一道DP. /* 2217 */ #include <iostream> #include <cstdio> #include <cstring> #incl ...