`
yanguz123
  • 浏览: 564929 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

\(^_^)/ Java 多线程下载例子

    博客分类:
  • Code
 
阅读更多

代码:

import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class DownUtil {
	// 定义下载资源的路径
	private String path;
	// 指定所下载的文件的保存位置
	private String targetFile;
	// 定义需要使用多少线程下载资源
	private int threadNum;
	// 定义下载的线程对象
	private DownThread[] threads;
	// 定义下载的文件的总大小
	private int fileSize;

	public DownUtil(String path, String targetFile, int threadNum) {
		this.path = path;
		this.threadNum = threadNum;
		// 初始化threads数组
		threads = new DownThread[threadNum];
		this.targetFile = targetFile;
	}

	public void download() throws Exception {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5 * 1000);
		conn.setRequestMethod("GET");
		conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
				+ "application/x-shockwave-flash, application/xaml+xml, " + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
				+ "application/x-ms-application, application/vnd.ms-excel, " + "application/vnd.ms-powerpoint, application/msword, */*");
		conn.setRequestProperty("Accept-Language", "zh-CN");
		conn.setRequestProperty("Charset", "UTF-8");
		conn.setRequestProperty("Connection", "Keep-Alive");
		// 得到文件大小
		fileSize = conn.getContentLength();
		conn.disconnect();
		int currentPartSize = fileSize / threadNum + 1;
		RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
		// 设置本地文件的大小
		file.setLength(fileSize);
		file.close();
		for (int i = 0; i < threadNum; i++) {
			// 计算每条线程的下载的开始位置
			int startPos = i * currentPartSize;
			// 每个线程使用一个RandomAccessFile进行下载
			RandomAccessFile currentPart = new RandomAccessFile(targetFile, "rw");
			// 定位该线程的下载位置
			currentPart.seek(startPos);
			// 创建下载线程
			threads[i] = new DownThread(startPos, currentPartSize, currentPart);
			// 启动下载线程
			threads[i].start();
		}
	}

	// 获取下载的完成百分比
	public double getCompleteRate() {
		// 统计多条线程已经下载的总大小
		int sumSize = 0;
		for (int i = 0; i < threadNum; i++) {
			sumSize += threads[i].length;
		}
		// 返回已经完成的百分比
		return sumSize * 1.0 / fileSize;
	}

	private class DownThread extends Thread {
		// 当前线程的下载位置
		private int startPos;
		// 定义当前线程负责下载的文件大小
		private int currentPartSize;
		// 当前线程需要下载的文件块
		private RandomAccessFile currentPart;
		// 定义已经该线程已下载的字节数
		public int length;

		public DownThread(int startPos, int currentPartSize, RandomAccessFile currentPart) {
			this.startPos = startPos;
			this.currentPartSize = currentPartSize;
			this.currentPart = currentPart;
		}

		@Override
		public void run() {
			try {
				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(5 * 1000);
				conn.setRequestMethod("GET");
				conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
						+ "application/x-shockwave-flash, application/xaml+xml, " + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
						+ "application/x-ms-application, application/vnd.ms-excel, " + "application/vnd.ms-powerpoint, application/msword, */*");
				conn.setRequestProperty("Accept-Language", "zh-CN");
				conn.setRequestProperty("Charset", "UTF-8");
				InputStream inStream = conn.getInputStream();
				// 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。
				inStream.skip(this.startPos);
				byte[] buffer = new byte[1024];
				int hasRead = 0;
				// 读取网络数据,并写入本地文件
				while (length < currentPartSize && (hasRead = inStream.read(buffer)) != -1) {
					currentPart.write(buffer, 0, hasRead);
					// 累计该线程下载的总大小
					length += hasRead;
				}
				currentPart.close();
				inStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws Exception {
		// 初始化DownUtil对象
		final DownUtil downUtil = new DownUtil("http://www.crazyit.org/" + "attachment.php?aid=MTY0NXxjNjBiYzNjN3wxMzE1NTQ2MjU5fGNhO"
				+ "DlKVmpXVmhpNGlkWmVzR2JZbnluZWpqSllOd3JzckdodXJOMUpOWWt0aTJz,", "oracelsql.rar", 4);
		// 开始下载
		downUtil.download();
		new Thread() {
			public void run() {
				while (downUtil.getCompleteRate() < 1) {
					// 每隔0.1秒查询一次任务的完成进度,
					// GUI程序中可根据该进度来绘制进度条
					System.out.println("已完成:" + downUtil.getCompleteRate());
					try {
						Thread.sleep(1000);
					} catch (Exception ex) {
					}
				}
			}
		}.start();
	}
}

 

分享到:
评论

相关推荐

    TCP.rar_java Tcp _tcp java_tcp 多线程_tcp多线程

    Java作为一种强大的编程语言,提供了丰富的API来支持TCP编程,使得开发者能够轻松地创建多线程TCP连接。本文将深入探讨如何使用Java实现多线程TCP连接,并涉及相关的关键知识点。 首先,TCP是一种面向连接的、可靠...

    java多线程例子

    Java 多线程例子 Java 多线程是 Java 编程语言中的一种基本概念,它允许程序同时执行多个任务,从而提高程序的性能和效率。本文将通过三个实用的例子,讲解 Java 多线程的基本概念和使用方法。 第一个例子:创建多...

    java多线程经典例子

    在Java多线程编程中,理解如何创建和...总的来说,这个例子展示了Java多线程的基本操作,包括创建、启动、管理和通信。理解和掌握这些概念对于进行并发编程是至关重要的,可以帮助开发者构建高效、稳定的多线程应用。

    java一个多线程的经典例子

    根据提供的文件信息,我们可以归纳出以下关于Java多线程的经典示例中的关键知识点: ### Java多线程实现方式 在Java中,实现多线程有两种主要的方法:通过继承`Thread`类或者实现`Runnable`接口。 #### 继承...

    java多线程下载代码

    在Java编程中,多线程下载是一种常见的优化技术,它能提高大文件下载的效率,通过将文件分割成多个部分并同时下载,可以显著减少总体下载时间。以下是一个基于Java实现多线程下载的基本概念和关键点: 1. **线程...

    java 多线程 控制按钮移动 例子

    总的来说,Java多线程提供了丰富的功能,包括线程的创建、启动、中断、同步以及异常处理等。通过合理利用这些工具,开发者可以构建出高效、稳定且响应迅速的多线程应用程序。在实际编程中,要特别注意线程安全和性能...

    java多线程的一个简单例子

    很简单的一个java多线程例子,希望多大家有帮助

    java多线程经典案例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...

    java多线程编程-详细炒作例子

    ### Java多线程编程详解与实战案例 #### 理解多线程概念与Java内存模型 多线程,作为现代编程中的一项关键技术,允许在单一应用程序中并发执行多个指令流,每个这样的指令流被称为一个线程。在Java中,线程被视为...

    java多线程示例

    在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。

    JAVA单线程多线程

    ### JAVA中的单线程与多线程概念解析 #### 单线程的理解 在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型...

    Java多线程下载的例子.doc

    在Java编程中,多线程下载是一种常见的优化策略,它能有效地提高文件下载速度,...这个Java多线程下载的例子展示了如何利用Java的并发特性提高效率,同时也提醒我们在实际开发中要关注线程安全、异常处理和资源管理。

    java 多线程小例子 很方便 很实用 适合初学者

    ### Java多线程小例子详解 #### 知识点一:基本多线程示例 在给定的代码示例中,我们首先看到的是一个简单的Java多线程应用实例。这个例子展示了如何创建并启动一个新的线程。在`ThreadDemo`类的`main`方法中,...

    Java多线程实现异步调用实例

    总之,Java多线程和异步调用是构建高效、响应迅速的应用程序的关键技术。通过合理利用这些工具和机制,开发者可以编写出能够充分利用多核处理器优势的代码,从而提高软件性能。在实际应用中,理解并熟练掌握这些概念...

    java中线程的应用例子

    在Java编程语言中,线程是程序执行的基本单元,它允许程序同时执行多个任务。Java中的线程模型是建立在操作系统级别的线程之上的,因此,通过Java的线程机制,开发者可以充分利用多核处理器的资源,提高程序的并发性...

    JAVA多线程的一个带UI界面的例子

    在Java编程中,多线程是一项关键特性,...总之,这个"JAVA多线程的一个带UI界面的例子"涵盖了Java多线程编程和GUI设计的核心概念,通过实际的代码示例,有助于开发者深入理解如何在实际应用中正确、高效地使用多线程。

    java 多线程的一个例子java 多线程的一个例子

    总结起来,这个Java多线程的例子展示了如何使用自定义数据结构和线程来表达线程间的依赖关系,并通过`Thread`对象和`Runnable`接口实现线程的创建和执行。理解这个例子有助于深入理解Java多线程的概念,以及如何在...

    java多线程例子(1).pdf

    java多线程例子(1).pdf java多线程例子(1).pdf java多线程例子(1).pdf

    Java多线程调用BlockingDeque跑批量数据的例子

    一个线程从A表读数据放入队列 N个线程从队列中取出数据,找到其在子表中的数据 对子表中的数据开3种线程:读,发email,标记状态 N个线程对完成的A表数据做最后处理 支持大数据量跑批,就是个例子,本来是公司发送...

Global site tag (gtag.js) - Google Analytics