- 浏览: 1590077 次
- 来自: 上海
文章分类
- 全部博客 (374)
- Java (101)
- Struts (54)
- Oracle (30)
- JavaScript (16)
- Spring (27)
- Hibernate (16)
- MyEclipse (3)
- JSF (1)
- FreeMarker (2)
- SiteMesh (2)
- JfreeChart (2)
- Ibatis (2)
- JSP (12)
- MyBatis (4)
- SWFupload (1)
- EJB (4)
- Jboss (4)
- WebService (2)
- Linux (16)
- Android (2)
- XML (6)
- Java 网络编程 (13)
- AXIS2 (1)
- FTP (1)
- Jswing (1)
- Socket (3)
- 杂文选集 (6)
- solr (2)
- PS (1)
- Tomcat (7)
- JDBC (9)
- Highcharts (1)
- maven (1)
- Nodejs (0)
- navicat (2)
- Exception (5)
- eclipse (3)
- jQuery (1)
- springMVC (4)
- MySQL (11)
- SVN (1)
- Sql Server (1)
- zookeeper (1)
- JVM (1)
- Groovy (2)
- Git (1)
- Nginx (1)
- DynamicReport (1)
- IDEA (2)
- JasperReports (1)
- Postgresql (2)
- Mac (1)
- gradle (1)
- 数据结构算法 (1)
最新评论
-
hpu145:
引用引用
java 千分位的添加和去除 -
被遗忘的下路:
少了个junit-4.8.2的包
SSH2整合完整案例(四十三) -
白天看黑夜:
java过滤emoji字符处理,希望能帮到你http://ww ...
emoji 表情图片解决方法 -
caipeiming:
这个挺好JavaScript实现input输入框控件只允许输入 ...
js 控制文本框只能输入中文、英文、数字等 -
双子树:
东西太好啦受教啊
Struts2 JSP中将list,set ,Map传递到Action然后<s:iterator>遍历(三十五)
http://wenku.baidu.com/view/57fd6d8002d276a200292eca.html
synchronized 这个是不是没有必要呢? 线程读取的都是不同的位置! 菜鸟一枚,勿喷!
我刚试试了下 ,不行 ,下载下来的 文件 破坏了,但是 大小是对的.
说明 多线程下载 是指 将一个文件分多个线程先下载, 但是写到同一个文件中的时候 必须按顺序写. 如果不是写到同一个文件 ,这里 就不需要 synchronized ,你看这样对吗?
我多线程下载,那么有可能后面的线程先完成流的下载,唯独第一块最慢,这时我下载中断,也就等于我所有的块都没传,因为写入文件必须按顺序,还得从第一块重新传。对吧,楼主?
synchronized 这个是不是没有必要呢? 线程读取的都是不同的位置! 菜鸟一枚,勿喷!
我刚试试了下 ,不行 ,下载下来的 文件 破坏了,但是 大小是对的.
说明 多线程下载 是指 将一个文件分多个线程先下载, 但是写到同一个文件中的时候 必须按顺序写. 如果不是写到同一个文件 ,这里 就不需要 synchronized ,你看这样对吗?
synchronized 这个是不是没有必要呢? 线程读取的都是不同的位置! 菜鸟一枚,勿喷!
package com.itheima.net.socket; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.io.Serializable; import java.net.HttpURLConnection; import java.net.URL; /** * 多线程断点续传 基于 (HTTP) * @author Bin * Windows NT 6.1 */ public class TextThreadsAndPointAdd { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String webAddr="http://nchc.dl.sourceforge.net/project/jtidy/JTidy/r938/jtidy-r938.zip"; String fileDir="F:/temp"; String fileName="ss.zip"; int count=5; new TextThreadsAndPointAdd(webAddr,fileDir,fileName,count); } public TextThreadsAndPointAdd(String webAddr,String fileDir,String fileName,int count) { try { TranBean bean=new TranBean(webAddr,fileDir,fileName,count); ControlFileFetch fileFetch=new ControlFileFetch(bean); fileFetch.start(); } catch (Exception e) { System.out.println("多线程下载文件出错:"+e.getMessage()); System.exit(1); } } } //扩展多线程类,负责文件的抓取,控制内部线程 class ControlFileFetch extends Thread{ TranBean tranBean=null; //扩展信息bean long [] startPosition; //开始位置 long [] endPosition; //结束位置 FileFetch[] childThread; //子线程对象 long fileLength; //文件长度 boolean isFitstGet=true; //是否第一次去文件 boolean isStopGet=false; //停止标志 File fileName; //文件下载的临时信息 DataOutputStream output; //输出到文件的输出流 public ControlFileFetch(TranBean tranBean){ this.tranBean=tranBean; fileName=new File(tranBean.getFileDir()+File.separator+tranBean.getFileName()+".info"); //创建文件 System.out.println(tranBean.getFileDir()+File.separator+tranBean.getFileName()+".info"); if(fileName.exists()){ isFitstGet=false; readInfo(); }else{ startPosition=new long[tranBean.getCount()]; endPosition =new long[tranBean.getCount()]; } } public void run(){ try { if(isFitstGet){ //第一次读取文件 fileLength=getFieldSize(); //调用方法获取文件长度 if(fileLength==-1){ System.err.println("文件长度为止"); }else if(fileLength==-2){ System.err.println("不能访问文件"); }else{ System.out.println("文件的长度:"+fileLength); //循环划分 每个线程要下载的文件的开始位置 for (int i = 0; i < startPosition.length; i++) { startPosition[i]=(long)(i*(fileLength/startPosition.length)); } //循环划分每个线程要下载的文件的结束位置 for (int i = 0; i < endPosition.length-1; i++) { endPosition[i]=startPosition[i+1]; } //设置最后一个 线程的下载 结束位置 文件的的长度 endPosition[endPosition.length-1]=fileLength; } } //创建 子线程数量的数组 childThread=new FileFetch[startPosition.length]; for (int i = 0; i < startPosition.length; i++) { childThread[i]=new FileFetch(tranBean.getWebAddr(), tranBean.getFileDir()+File.separator+tranBean.getFileName(), startPosition[i], endPosition[i], i); Log.log("线程"+(i+1)+",的开始位置="+startPosition[i]+",结束位置="+endPosition[i]); childThread[i].start(); } boolean breakWhile=false; while (!isStopGet) { savePosition(); Log.sleep(500);// breakWhile=true; for (int i = 0; i < startPosition.length; i++) { //循环实现下载文件 if(!childThread[i].downLoadOver){ breakWhile=false; break; } } if(breakWhile) break; } System.err.println("文件下载结束!"); } catch (Exception e) { System.out.println("下载文件出错:"+e.getMessage()); } } //保存下载信息(文件指针信息) private void savePosition() { try { output=new DataOutputStream(new FileOutputStream(fileName)); output.writeInt(startPosition.length); for (int i = 0; i < startPosition.length; i++) { output.writeLong(childThread[i].startPosition); output.writeLong(childThread[i].endPosition); } output.close(); } catch (Exception e) { System.out.println("保存下载信息出错:"+e.getMessage()); } } //获得文件的长度 public long getFieldSize(){ int fileLength=-1; try { URL url=new URL(tranBean.getWebAddr()); //根据网址传入网址创建URL对象 //打开连接对象 HttpURLConnection httpConnection=(HttpURLConnection)url.openConnection(); //设置描述发出HTTP请求的终端信息 httpConnection.setRequestProperty("User-Agent", "NetFox"); int responseCode=httpConnection.getResponseCode(); //表示不能访问文件 if(responseCode>=400){ errorCode(responseCode); return -2; } String head; for (int i = 1; ; i++) { head=httpConnection.getHeaderFieldKey(i); //获取文件头部信息 if(head !=null){ if(head.equals("Content-Length")){ //根据头部信息获取文件长度 fileLength=Integer.parseInt(httpConnection.getHeaderField(head)); break; } }else{ break; } } } catch (Exception e) { System.out.println("获取文件长度出错:"+e.getMessage()); } Log.log("文件长度"+fileLength); return fileLength; } private void errorCode(int errorCode){ System.out.println("错误代码:"+errorCode); } //读取文件指针位置 private void readInfo(){ try { //创建数据输出流 DataInputStream input=new DataInputStream(new FileInputStream(fileName)); int count=input.readInt(); //读取分成的线程下载个数 startPosition=new long[count]; //设置开始线程 endPosition=new long[count]; //设置结束线程 for (int i = 0; i < startPosition.length; i++) { startPosition[i]=input.readLong(); //读取每个线程的开始位置 endPosition[i]=input.readLong(); //读取每个线程的结束位置 } input.close(); } catch (Exception e) { System.out.println("读取文件指针位置出错:"+e.getMessage()); } } } //扩展线程类,实现部分文件的抓取 class FileFetch extends Thread{ String webAddr; //网址 long startPosition; //开始位置 long endPosition; //结束位置 int threadID; //线程编号 boolean downLoadOver=false; //下载结束 boolean isStopGet=false; //是否停止请求 FileAccess fileAccessI=null; //存储文件的类 public FileFetch(String surl,String sname, long startPosition, long endPosition, int threadID) throws IOException { this.webAddr = surl; this.startPosition = startPosition; this.endPosition = endPosition; this.threadID = threadID; this.fileAccessI = new FileAccess(sname,startPosition); } //实现线程的方法 public void run(){ while (startPosition < endPosition && !isStopGet) { try { URL url=new URL(webAddr); //根据网络资源创建URL对象 HttpURLConnection httpConnection=(HttpURLConnection)url.openConnection(); //创建 打开的连接对象 //设置描述发出的HTTP请求的终端的信息 httpConnection.setRequestProperty("User-Agent", "NetFox"); String sproperty="byte="+startPosition+"-"; httpConnection.setRequestProperty("RANGE", sproperty); Log.log(sproperty); //获取 网络资源的输入流 InputStream input=httpConnection.getInputStream(); byte[] b=new byte[1024]; int nRead; //循环将文件下载制定目录 while ((nRead=input.read(b, 0, 1024))>0 && startPosition < endPosition && !isStopGet) { startPosition+=fileAccessI.write(b, 0, nRead); //调用方法将内容写入文件 } Log.log("线程\t"+(threadID+1)+"\t结束...."); downLoadOver=true; } catch (Exception e) { e.printStackTrace(); } } } //打印回应的头的信息 public void logResponseHead(HttpURLConnection con){ for (int i = 1; ; i++) { String header=con.getHeaderFieldKey(i); //循环答应回应的头信息 if(header!=null){ Log.log(header+":"+con.getHeaderField(header)); }else break; } } public void splitterStop(){ isStopGet=true; } } //存储文件的类 class FileAccess implements Serializable{ RandomAccessFile saveFile; //要保存的文件 long position; public FileAccess() throws IOException { this("",0); } public FileAccess(String sname, long position) throws IOException { this.saveFile =new RandomAccessFile(sname, "rw"); //创建随机读取对象, 以 读/写的方式 this.position = position; saveFile.seek(position); //设置指针位置 } //将字符数据 写入文件 public synchronized int write(byte[] b,int start,int length){ int n=-1; try { saveFile.write(b,start,length); n=length; } catch (Exception e) { e.printStackTrace(); } return n; } } //传输保存信息的类 class TranBean { private String webAddr; //下载地址 private String fileDir; //下载到指定的目录 private String fileName; //下载后文件的新名字 private int count; //文件分几个线程下载, 默认为 3个 public TranBean() { //默认的构造方法 this("","","",3); } //带参数的构造方法 public TranBean(String webAddr, String fileDir, String fileName, int count) { this.webAddr = webAddr; this.fileDir = fileDir; this.fileName = fileName; this.count = count; } public String getWebAddr() { return webAddr; } public void setWebAddr(String webAddr) { this.webAddr = webAddr; } public String getFileDir() { return fileDir; } public void setFileDir(String fileDir) { this.fileDir = fileDir; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } } //线程运行信息显示的日志类 class Log{ public Log(){} public static void sleep(int nsecond){ try { Thread.sleep(nsecond); } catch (Exception e) { System.out.println("线程沉睡"); } } public static void log(String message){ //显示日志信息 System.err.println(message); } public static void log(int message){ //显示日志信息 System.err.println(message); } }
评论
3 楼
zy116494718
2015-08-10
Luob. 写道
yao752915708 写道
//将字符数据 写入文件 public synchronized int write(byte[] b,int start,int length){ int n=-1; try { saveFile.write(b,start,length); n=length; } catch (Exception e) { e.printStackTrace(); } return n; } }
synchronized 这个是不是没有必要呢? 线程读取的都是不同的位置! 菜鸟一枚,勿喷!
我刚试试了下 ,不行 ,下载下来的 文件 破坏了,但是 大小是对的.
说明 多线程下载 是指 将一个文件分多个线程先下载, 但是写到同一个文件中的时候 必须按顺序写. 如果不是写到同一个文件 ,这里 就不需要 synchronized ,你看这样对吗?
我多线程下载,那么有可能后面的线程先完成流的下载,唯独第一块最慢,这时我下载中断,也就等于我所有的块都没传,因为写入文件必须按顺序,还得从第一块重新传。对吧,楼主?
2 楼
Luob.
2013-03-14
yao752915708 写道
//将字符数据 写入文件 public synchronized int write(byte[] b,int start,int length){ int n=-1; try { saveFile.write(b,start,length); n=length; } catch (Exception e) { e.printStackTrace(); } return n; } }
synchronized 这个是不是没有必要呢? 线程读取的都是不同的位置! 菜鸟一枚,勿喷!
我刚试试了下 ,不行 ,下载下来的 文件 破坏了,但是 大小是对的.
说明 多线程下载 是指 将一个文件分多个线程先下载, 但是写到同一个文件中的时候 必须按顺序写. 如果不是写到同一个文件 ,这里 就不需要 synchronized ,你看这样对吗?
1 楼
yao752915708
2013-03-14
//将字符数据 写入文件 public synchronized int write(byte[] b,int start,int length){ int n=-1; try { saveFile.write(b,start,length); n=length; } catch (Exception e) { e.printStackTrace(); } return n; } }
synchronized 这个是不是没有必要呢? 线程读取的都是不同的位置! 菜鸟一枚,勿喷!
发表评论
-
POST发送XML数据
2013-10-16 14:09 9977package com.itheima.xml; i ... -
发送 GET 和 POST请求
2013-10-05 11:28 3310/** *@param url 发送请求的url ... -
Java 多线程断点续传 (基于HTTP)
2013-03-13 23:13 957http://wenku.baidu.com/view/57f ... -
Socket 点对点 通信
2013-03-13 12:54 4382Socket通常称作为 "套接字",用于描 ... -
Socket 点对面 通信
2013-03-13 12:53 1586Socket 点对面 通信 创建多客户连接的socket通信 ... -
Socket 点对点通信
2013-03-12 20:07 934Socket通常称作为 "套接字",用于描 ... -
FTP 上传 下载 登录
2013-03-12 11:20 32221.使用 Serv-U 在本机上创建一个 FTP服务器 h ... -
FTP 登录 下载 上传 文件
2013-03-11 22:43 101.使用 Serv-U 在本机上创建一个 FTP服务器 h ... -
URL 获取网络资源
2013-03-11 09:23 1980URL 获取网络资源 packag ... -
IP地址和域名的获取
2013-03-10 21:44 1444InetAddress 获取 IP地址和域名 packag ... -
Java 抓取网页上的图片
2012-09-23 17:28 12625本文介绍 1.利用正则 匹 ... -
java 下载网络上的图片并保存到本地目录
2012-09-22 02:32 57453import java.io.File; import ... -
java 根据URL获取网页源码
2012-09-21 00:20 11275import java.io.BufferedReader ...
相关推荐
Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多...
Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与...
JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多...
同时,"【成品】多线程断点续传工具.jar"可能是一个可执行的Java应用程序,它提供了用户界面或者命令行工具,让用户可以方便地进行断点续传的文件上传。 多线程断点续传进一步提高了文件传输的效率。通过将文件分割...
基于Java多线程与线程安全实践-基于Http协议的断点续传设计与实现.zip基于Java多线程与线程安全实践-基于Http协议的断点续传设计与实现.zip基于Java多线程与线程安全实践-基于Http协议的断点续传设计与实现.zip基于...
Java多线程与线程安全实践-基于Http协议的断点续传(毕业设计+课程设计)Java多线程与线程安全实践-基于Http协议的断点续传(毕业设计+课程设计)Java多线程与线程安全实践-基于Http协议的断点续传(毕业设计+课程...
Java多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传...
【标题】"Java毕业设计-多线程与线程安全实践-基于Http协议的断点续传.zip"涉及的核心知识点主要包括Java多线程编程、线程安全、HTTP协议以及文件的断点续传技术。 Java多线程编程是Java语言的一大特性,它允许程序...
Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-...
基于Http协议的断点续传-Java多线程与线程安全实践编程.zip 基于Http协议的断点续传-Java多线程与线程安全实践编程.zip 基于Http协议的断点续传-Java多线程与线程安全实践编程.zip 基于Http协议的断点续传-Java多...
在这个“基于Java的多线程断点续传程序”中,我们主要关注的是如何利用Java的多线程特性和网络编程能力来实现文件的断点续传功能。这个程序可能是为了满足在不完整的下载过程中能够继续从上次中断的位置开始下载的...
javaweb毕业设计-Java多线程与线程安全实践-基于Http协议的断点续传(可做课程设计).rarjavaweb毕业设计-Java多线程与线程安全实践-基于Http协议的断点续传(可做课程设计).rarjavaweb毕业设计-Java多线程与线程安全...
这个是java开发的多线程断点续传下载demo,内有详细注释,是练习android多线程断点续传下载时写的测试demo,下面的android开发的多线程断点续传下载demo是基于这个移植过去的,使用java开发的可以参考这个。
总结的教程文档"点对点多线程断点续传的实现.doc"可能详细阐述了这些技术的实现细节,包括具体编程语言(如Java、C++或Python)的实现示例,以及如何将这些技术整合到实际应用中。而"www.pudn.com.txt"可能是该教程...
标题:“Java多线程与线程安全实践-基于Http协议的断点续传论文” 描述:文档是一篇论文,主题集中在Java多线程技术的应用实践,特别是通过HTTP协议实现下载过程中的断点续传功能。 标签:技术及资料 知识点说明...