多线程下载

如何在磁盘上直接设置一个文件的大小

	public static void main(String[] args) throws Exception {
		RandomAccessFile  r=new RandomAccessFile("f:/a.avi", "rw");
		r.setLength(1024*1024);
		r.close();
	}

/**
 * 多线程下载同一个文件
       思想:
 *
 */
public class MultiThreadDown {
	public MultiThreadDown() throws Exception {
		//声明url
		String path = "http://localhost:6666/day23/up/bin.zip";
		//第一步:声明url对象
		URL url = new URL(path);
		//第二步:返回连接对象
		HttpURLConnection con = (HttpURLConnection) url.openConnection();
		//第三步:设置请求类型
		con.setRequestMethod("GET");
		//第四步接收信息
		con.setDoInput(true);
		//第五步:连接
		con.connect();
		//6:状态码
		int code = con.getResponseCode();
		if(code==200){
			//7:数据的长度
			int sum = con.getContentLength();
			System.err.println("总文件的大小:"+sum);
			//7.1有了文件的长度,直接创建一个相同大小的文件
			String fileName = "d:/a/bin.zip";
			RandomAccessFile file = new RandomAccessFile(new File(fileName),"rw");
			file.setLength(sum);
			file.close();
			//8:声明线程的个数
			int threadCount = 3;
			//9:计算每个线程的下载量
			int threadSize = sum/threadCount +(sum%threadCount==0?0:1);
			System.err.println("每个线程下载的数据量:"+threadSize);
			//10:计算每个线程下载的数据量
			for(int i=0;i<threadCount;i++){
				int start =i*threadSize;
				int end = start+(threadSize-1);
				System.err.println("第"+(i+1)+"个线程应该下载的是:bytes="+start+"-"+end);
				//启动多个线程
				new MyDownThread(url,fileName,start,end).start();
			}
		
		}
		con.disconnect();
	}
	public static void main(String[] args) throws Exception {
		new MultiThreadDown();
	}
}
/**
 * 所有线程要知
 * 道url地址
 * 写哪一个文件
 * 从哪儿开始写
 * 一共多少字节,数据
 */
class MyDownThread extends Thread{
	private URL url;
	private String fileName;
	private int start;
	private int end;
	public MyDownThread(URL url, String fileName, int start, int end) {
		this.url = url;
		this.fileName = fileName;
		this.start = start;
		this.end = end;
	}
	@Override
	public void run() {
		try{
			//打开连接
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			//设置
			con.setRequestMethod("GET");
			con.setDoInput(true);
			//设置从哪儿开始下载数据
			con.setRequestProperty("range","bytes="+start+"-"+end);
			con.connect();
			int code = con.getResponseCode();
			if(code==206){
				int size = con.getContentLength();
				System.err.println("线程:"+this.getName()+",下载的数据量为:"+size);
				InputStream in = con.getInputStream();
				//写同一文件
				RandomAccessFile file = new RandomAccessFile(new File(fileName),"rw");
				//设置从文件的什么位置开始写数据
				file.seek(start);
				//读取数据
				byte[] b = new byte[1024];
				int len = 0;
				while((len=in.read(b))!=-1){
					file.write(b,0,len);
				}
				file.close();
			}
			con.disconnect();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}



项目示例

第一步:分析:
任何人都可以上传图片。只接收图片
提供一个上传页面,在后台servlet判断文件类型。Fileitem.getContentType();
上传图片可以带一个说明。
提供一个普通表单项目text
后台fileitem.isFormFileld()==true

保存到数据
两个工作:
1:将信息放到数据表中。
2:文件上传到某个目录。

任何人都可以看到所的有图片
提供一个超连接
通过一个serlvet查询表中所有的行。图片的名称

提供删除图片的能力。要求谁上传的图片,就由某人来删除。
删除两个地方:
1:删除数据库行.
2:删除这个文件。
限制:
根据IP做一个基本限制。


提供下载功能:
将uuuid.jpg修改成以前的名称.oldname.jpg.

看小图的列表,点小图应该看大图.

第二步:设计一个数据表
用来保存图片的信息
Imgs
Id
Oldname
Newname
Dt
Ip
note


create database imgs character set UTF8;
use imgs;
create table imgs(
   id varchar(32) primary key,
   oldname varchar(100),
   newname varchar(100),
   dt char(19),
   ip varchar(20),
   note varchar(100)
);

第三步:先实现上传
导包
两个功能:
1:保存数据。
2:实现上传。
修改名称。

public class UpServlet extends HttpServlet {
	private UpService service= new UpService();
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		DiskFileItemFactory disk = 
				new DiskFileItemFactory();
		try{
			ServletFileUpload up = 
					new ServletFileUpload(disk);
			List<FileItem> list = up.parseRequest(request);
			//声明一个image对象
			Image img = new Image();
			img.setIp(request.getRemoteAddr());
			for(FileItem item:list){
				if(item.isFormField()){
					String note = item.getString(request.getCharacterEncoding());
					img.setNote(note);
				}else{
					String oldName = item.getName();
					String type = item.getContentType();
					if(!type.contains("image/")){
						throw new RuntimeException("不接收的类型");
					}
					oldName = oldName.substring(oldName.lastIndexOf("\\")+1);
					String ext = oldName.substring(oldName.lastIndexOf("."));
					String newName = 
							Day23Utils.getUUID()+ext;
					img.setOldname(oldName);
					img.setNewname(newName);
					
					//上传
					String path = getServletContext().getRealPath("/up");
					item.write(new File(path+"/"+newName));
					item.delete();
				}
			}
			service.save(img);
		}catch(Exception e){
			throw new RuntimeException(e);
		}
	}
}

第四步:实现显示所有小图

Cn.itcast.show
ShowServlet
放到request
转发到一个页面显示
ShowSerivce
ShowDao
….
此功能非常简单(略).

public class ShowServlet extends HttpServlet {
	private ShowService service = new ShowService();
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		List<Image> list = service.queryAll();
		//放到requs
		request.setAttribute("imgs",list);
		//转发,必须以/开始,是指从项目的根开始找资源
		getServletContext().getRequestDispatcher("/jsps/show.jsp").forward(request, response);
	}
}


第四步:实现删除功能
根据图片的id,找到这个图片。判断是否是同一个ip。
Cn.itcast.del



第五步;下载功能


3、 断点分类
a) 局部断点。
b) 异常断点。出现错误时才进入错误的位置。
c) 观察点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值