`

使用多线程拆分文件下载

阅读更多
首先我们从任意的一个地方获得资源,考虑到你的带宽创建线程
我们现在创建一个简单的多线程解析资源

public class DownLoadRunable implements Runnable {
	private int threadId;
	private int startIndex;
	private int endIndex;
	private String path;
	
	public DownLoadRunable(String path,int threadId, int startIndex, int endIndex) {
		super();
		this.threadId = threadId;
		this.startIndex = startIndex;
		this.endIndex = endIndex;
		this.path = path;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		URL url;
		try {
			url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			// 重要:请求服务器下载部分文件 指定文件的位置
			conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
			// 从服务器请求全部资源返回200 ok如果从服务器请求部分资源 返回 206 ok
			int code = conn.getResponseCode();
			System.out.println("code:" + code);
			InputStream is = conn.getInputStream();// 已经设置了请求的位置,返回的是当前位置对应的文件的输入流
			RandomAccessFile raf = new RandomAccessFile("meinv.jpg", "rwd");
			// 随机写文件的时候从哪个位置开始写
			raf.seek(startIndex);// 定位文件
			int len = 0;
			byte[] buffer = new byte[1024];
			while ((len = is.read(buffer)) != -1) {
				raf.write(buffer, 0, len);
			}
			is.close();
			raf.close();
			System.out.println("线程:" + threadId + "下载完毕");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}


/**
 * @author Janle
 *
 */
public class DowloadDemo {
	// 文件路径
	public static String[] paths = { "http://img.ugirls.com/uploads/cooperate/baidu/20160408jzx3.jpg",
			"http://b.hiphotos.baidu.com/image/h%3D360/sign=a813da3172094b36c4921deb93ce7c00/810a19d8bc3eb135aa449355a21ea8d3fc1f4458.jpg",
			"http://a.hiphotos.baidu.com/image/h%3D360/sign=c429bad21dd8bc3ed90800ccb28aa6c8/e7cd7b899e510fb3a78c787fdd33c895d0430c44.jpg" };
	// 线程数
	public static int threadCount = 3;
	private static ExecutorService threads = Executors.newFixedThreadPool(4);

	public static void main(String[] args) {
		try {
			for (String path : paths) {
				// 1.连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件
				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				conn.setConnectTimeout(5000);
				conn.setRequestMethod("GET");
				int code = conn.getResponseCode();// 获得相应的状态码如果是200就说明请求成功
				if (code == 200) {
					splitTaskToThread(path, conn.getContentLength());
				}
			}
			threads.shutdown();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将资源拆分到线程资源中
	 * 
	 * @param fileSize
	 */
	private static void splitTaskToThread(String path, int fileSize) {
		// 假设是3个线程去下载资源。
		// 平均每一个线程下载的文件大小.
		int blockSize = fileSize / threadCount;// 线程执行块的大小
		for (int threadId = 1; threadId <= threadCount; threadId++) {
			// 线程下载的开始位置
			int startIndex = (threadId - 1) * blockSize;// 线程执行开始位置
			int endIndex = threadId * blockSize - 1;
			if (threadId == threadCount) {// 如果任务分配线程和线程的数量相同的时候直接将最后位置给截止位置【最后一块稍微大点】
				endIndex = fileSize;
			}
			threads.execute(new DownLoadRunable(path, startIndex, endIndex));
		}
	}
}

class DownLoadRunable implements Runnable {
	private int startIndex;
	private int endIndex;
	private String path;

	public DownLoadRunable(String path, int startIndex, int endIndex) {
		super();
		this.startIndex = startIndex;
		this.endIndex = endIndex;
		this.path = path;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		URL url;
		try {
			url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			// 重要:请求服务器下载部分文件 指定文件的位置
			conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);
			// 从服务器请求全部资源返回200 ok如果从服务器请求部分资源 返回 206 ok
			int code = conn.getResponseCode();
			System.out.println("code:" + code);
			InputStream is = conn.getInputStream();// 已经设置了请求的位置,返回的是当前位置对应的文件的输入流
			String urlPath = conn.getURL().getFile();
			String fileFullName = urlPath.substring(urlPath.lastIndexOf("/") + 1);
			RandomAccessFile raf = new RandomAccessFile(fileFullName, "rwd");
			// 随机写文件的时候从哪个位置开始写
			raf.seek(startIndex);// 定位文件
			int len = 0;
			byte[] buffer = new byte[1024];
			while ((len = is.read(buffer)) != -1) {
				raf.write(buffer, 0, len);
			}
			is.close();
			raf.close();
			System.out.println("线程:" + Thread.currentThread().getName() + "下载完毕");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}





多线程分发
(size / nThreads * i, size / nThreads * (i + 1));
分享到:
评论

相关推荐

    多线程拆分,合并文件

    NULL 博文链接:https://wentise.iteye.com/blog/1472493

    多线程下载文件

    1. **任务拆分**:多线程下载首先将大文件分割成多个小块,每个线程负责下载一个或多个数据块。这样,当多个线程同时工作时,可以从服务器并行获取文件的不同部分,显著提高下载速度。 2. **同步机制**:由于多个...

    java多线程文件传输

    在Java中,多线程可以提高程序的执行效率,尤其在处理并发任务时,如大文件的上传、下载和传输。下面将详细探讨相关知识点。 1. **线程基础** - **线程定义**:线程是操作系统分配CPU时间的基本单位,是程序执行的...

    多线程下载工具

    标题中的“多线程下载工具”指的是一个利用多线程技术加速文件下载的应用程序。...而对于普通用户,了解这类工具的工作方式能让他们更好地理解为何在某些情况下,使用多线程下载工具可以更快地获取所需文件。

    多线程下载及断点续传

    在IT领域,多线程下载和断点续传是提高文件下载效率和用户体验的重要技术。这两者结合使用,可以显著优化大文件的下载过程,尤其是对于网络环境不稳定的情况。 首先,我们来理解“多线程”这个概念。线程是操作系统...

    线程池管理多线程上传

    - `threadpooltask`可能包含实现线程池管理多线程上传的示例代码,包括文件拆分、任务提交、线程池配置等。具体实现方式会涉及到IO操作、并发控制、异常处理等多个方面。 总结来说,线程池通过统一管理和复用线程...

    使用itextpdf将PDF大文件拆分成若干份指定大小文件.zip

    同时,为了提高性能,可能需要使用多线程来处理大量页面,但这增加了实现的复杂性。 总之,利用iTextPDF库,通过计算和动态调整,我们可以有效地将一个大PDF文件拆分成多个指定大小的文件,以满足特定的存储和传输...

    C# 多线程查找文件

    本篇文章将深入探讨如何使用C#进行多线程查找文件,并分析其背后的原理和实现细节。 首先,我们要理解C#中多线程的基本概念。一个线程是程序执行的单一顺序控制流,而多线程则是同时运行两个或更多个这样的控制流。...

    java使用多线程读取超大文件

    Java使用多线程读取超大文件 Java使用多线程读取超大文件是指在java语言中使用多线程技术来读取超大文件,以提高读取速度和效率。下面是该技术的详细介绍和实现方法。 多线程读取超大文件的必要性 在读取超大文件...

    FFmpegH264 多线程 优化

    FFmpeg是一款开源的多媒体处理工具,它包含了各种编解码...在分析和使用提供的压缩包文件"ffmpegH264Opt"时,开发者可以深入研究源代码,理解并学习如何在FFmpeg中实现多线程和硬件优化,以优化自己的多媒体应用程序。

    多文件多线程断点下载

    在IT领域,多文件多线程断点下载是一种常见的优化技术,尤其在处理大文件或者网络不稳定时,这种技术能够显著提升下载效率并提供更好的用户体验。以下是对这一主题的详细阐述: 多线程技术是并发编程的核心,它允许...

    poi多线程大数据导出excel文件.zip

    本项目“poi多线程大数据导出excel文件”提供了一个解决方案,利用多线程来提高Excel的大数据导出效率。 Apache POI 3.1版本是较早的版本,而项目中使用了更新的4.1版本,这意味着它可能利用了更多优化和新特性。在...

    Socket实现文件上传下载,含多线程

    在本示例中,"Socket实现文件上传下载,含多线程" 提到了通过Socket在客户端和服务器之间进行文件传输,并且服务器端采用了多线程处理连接请求,提高了服务的并发能力。下面我们将详细探讨相关的知识点。 1. **...

    多线程传输工具

    标题中的“多线程传输工具”指的是利用计算机的多核处理器资源,通过开启多个并行的数据传输线程来提高文件下载或网页加载的速度。在单线程环境下,数据的传输通常受到网络带宽和处理能力的限制,而多线程技术能够...

    多线程导入excel 数据

    在Java编程中,多线程导入Excel数据是一项常见的任务,特别是在大数据处理和高并发场景下。...例如,文件`BigdataTest.java`可能是实现上述功能的一个测试类,通过它我们可以模拟并测试导入Excel数据的多线程场景。

    多任务、多线程下载

    在IT行业中,多任务、多线程下载是一种提高下载效率的技术,尤其在处理大文件或者多个文件下载时,它的优势尤为明显。通过并发执行下载任务,可以充分利用网络带宽资源,减少用户等待时间,提高用户体验。这篇博客...

    基于多线程的下载

    在下载场景中,多线程可以将大文件拆分成若干小块,同时从服务器获取,从而加快下载速度,减少网络阻塞的影响。 2.2 HTTP协议 HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议。在下载过程中,HTTP协议...

    csv拆分-大文件大数据大表格千万级数据批量拆分分割工具

    首先,我要介绍的是一款由“勤学道人”开发的高性能一键合并工具——...需要下载安装,初次使用可能需要一定的学习时间 特色功能: 支持单表千万量级拆分 支持批量拆分 支持带表头拆分 高性能:Python应用,支持多线程

    e语言-易语言多线程文件传输模块

    在文件传输场景下,多线程可以将大文件分割成若干小块,同时进行上传或下载,从而大大减少了整体的传输时间。 易语言多线程文件传输模块的实现,主要依赖于两个关键部分:易语言的扩展界面支持库和API函数的调用。...

    java 多线程技术下载文件

    总的来说,使用Java多线程技术下载文件是一种有效的提高下载效率的方法。通过合理的线程管理和数据分块,可以充分利用网络资源,减少因网络波动造成的下载中断,并允许用户在下载过程中暂停和恢复。这种方法在大型...

Global site tag (gtag.js) - Google Analytics