论坛首页 编程语言技术论坛

利用RandomAccessFile 实现多线程下载。

浏览 6995 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-19  
没事写个 多线程下载的例子,虽然项目中下载没用到
我想知道,如果使用了多线程下载,当多用户同时对这一个资源进行下载的时候会怎么样。有木有这样的文推荐。这是个随手写的程序,如果问题,希望讨论下。
class  --MyMutilDown

public class MyMutilDown {
/**
	 * 单线程的远程下载
	 */
	public void testOneTDown(String filePath, String url) {
		try {
			// 要写入的文件
			File file = new File(filePath + getFileExtName(url));
			FileWriter fWriter = new FileWriter(file);
			URL ul = new URL(url);
			URLConnection conn = ul.openConnection();
			conn.setConnectTimeout(2000);// 请求超时时间
			// int len = conn.getContentLength();
			InputStream in = conn.getInputStream();
			// byte[] by = new byte[1024];
			int temp = 0;
			while ((temp = in.read()) != -1) {
				fWriter.write(temp);
			}
			fWriter.close();
			in.close();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 文件后缀名
	 * 
	 * @param path
	 * @return
	 */
	public String getFileExtName(String path) {
		return path.substring(path.lastIndexOf("."));
	}
/**
	 * 测试多线程
	 * 
	 * @param filePath
	 *            文件保存路径
	 * @param url
	 *            url
	 * @param tnum
	 *            线程数量
	 */
	public void testMoreTDown(String filePath, String url, int tnum) {
		try {
			// 要写入的文件
			final File file = new File(filePath + getFileExtName(url));
			RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");// 建立随机访问
			final URL ul = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) ul.openConnection();
			conn.setConnectTimeout(2000);// 请求超时时间
			conn.setRequestMethod("GET");
			int len = conn.getContentLength();// 文件长度
			accessFile.setLength(len);
			accessFile.close();
			final int block = (len + tnum - 1) / tnum;// 每个线程下载的快大小
			
			for (int i = 0; i < tnum; i++) {
				final int a = i;
				new Thread(new Runnable() {
					int start = block * a;// 开始位置
					int end = block * (a + 1) - 1;// 结束位置
					@Override
					public void run() {
						HttpURLConnection conn2 = null;
						RandomAccessFile accessFile2 = null;
						InputStream in = null;
						try {
							conn2 = (HttpURLConnection) ul.openConnection();
							conn2.setConnectTimeout(2000);// 请求超时时间
							conn2.setRequestMethod("GET");
							// TODO Auto-generated method stub
							conn2.setRequestProperty("Range", "bytes=" + start
									+ "-" + end + "");// 设置一般请求属性 范围
							in = conn2.getInputStream();
							byte[] data = new byte[1024];
							int len = 0;
							accessFile2 = new RandomAccessFile(file, "rwd");
							accessFile2.seek(start);
							
							while ((len = in.read(data)) != -1) {
								accessFile2.write(data, 0, len);
							}
							System.out.println("线程:" + a + "下载完成!");
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						} finally {
							try {
								accessFile2.close();
								in.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}

						}
					}
				}).start();
			  
			}
			

		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		MyMutilDown mydown = new MyMutilDown();
		String path = "http://static.ishare.down.sina.com.cn/5585234.txt?ssig=f7CrV3UL8%2B&Expires=1347724800&KID=sina,ishare&ip=1347592902,117.40.138.&fn=%E5%8E%9A%E9%BB%91%E5%AD%A6.TXT";
		// mydown.downLoad(path, "D:\\aa", 1);
		// mydown.testOneTDown("D:\\", path);
		mydown.testMoreTDown("D:\\aa", path, 3);
	}
}







   发表时间:2012-12-20  
功能不错,只不过觉得不知道该用在那里,如果说是断网以后,联网可以继续下载,还是蛮有用的
  • 大小: 1.2 KB
  • 大小: 1.1 KB
0 请登录后投票
   发表时间:2012-12-21  
断点续传要看服务器支持不支持了
0 请登录后投票
   发表时间:2012-12-21  
为什么一个同时下载的资源,需要用到随机访问?
0 请登录后投票
   发表时间:2012-12-21  
Shen.Yiyang 写道
为什么一个同时下载的资源,需要用到随机访问?

他这里的实现就是把一个文件一次性初始化好一定的大小,然后根据需要切成几个块。跟着通过多线程去获取数据,每个线程将获取的那块数据放到特定的位置。
0 请登录后投票
   发表时间:2012-12-21  
freezingsky 写道
Shen.Yiyang 写道
为什么一个同时下载的资源,需要用到随机访问?

他这里的实现就是把一个文件一次性初始化好一定的大小,然后根据需要切成几个块。跟着通过多线程去获取数据,每个线程将获取的那块数据放到特定的位置。

嗯 是这样的 因为RandomAccessFile  的文件指针可以记录文件写入的记录,用多线程分割了文件大小,同时下载快大小就行了。
0 请登录后投票
   发表时间:2012-12-22  
不错, 保留,
没准哪天就要用这个类内.
0 请登录后投票
   发表时间:2012-12-24  
下载速度的瓶颈在读文件么,还是网络带宽。
还有多线程真的能提高读文件的速度么。

0 请登录后投票
   发表时间:2012-12-26  
freezingsky 写道
Shen.Yiyang 写道
为什么一个同时下载的资源,需要用到随机访问?

他这里的实现就是把一个文件一次性初始化好一定的大小,然后根据需要切成几个块。跟着通过多线程去获取数据,每个线程将获取的那块数据放到特定的位置。

OK....多线程用http range分段下载,然后同时写本地文件。 我还以为是服务端的什么事情
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics