如何使用多线程分片下载视频

package dhcc.io;

import java.io.*;

public class MutiCopyFileUtil {
	private String src; // 源文件
	private String dst; // 目标文件
	private int threadSize; // 开启的线程数

	public MutiCopyFileUtil(String src, String dst, int threadSize) {
		this.src = src;
		this.dst = dst;
		this.threadSize = threadSize;
	}

	// 拷贝文件的方法
	public void copyFile() {
		File file = new File(src); // 源文件的File对象
		long fsize = file.length(); // 源文件的大小(字节数)
		// 每个线程要下载的文件块的大小(字节数)
		long block = (fsize % threadSize == 0) ? (fsize / threadSize) : (fsize
				/ threadSize + 1);

		for (int threadId = 0; threadId < threadSize; threadId++) {
			// 开启多个线程进行文件的复制,每个线程复制一段区域
			new DownLoadThread(fsize, block, threadId).start();
		}
	}

	// 开启线程(内部类)
	private class DownLoadThread extends Thread {
		private long fsize; // 文件大小
		private long block; // 每个线程要下载的字节数大小
		private int threadId; // 线程的ID号,从0开始
		private int bufferSize = 1024*1024*5*10; // 缓冲区的大小(1M)

		public DownLoadThread(long fsize, long block, int threadId) {
			this.fsize = fsize;
			this.block = block;
			this.threadId = threadId;
		}

		@Override
		public void run() {
			try {
				// 以只读的方式读取源文件
				RandomAccessFile reader = new RandomAccessFile(src, "r");
				// 以读写的方法写入目标文件
				RandomAccessFile writer = new RandomAccessFile(dst, "rw");

				long startPosition = threadId * block; // 每个线程复制的文件起始位置
				// 确定每个线程复制的文件结束位置
				long endPosition = startPosition + block > fsize ? fsize
						: startPosition + block;

				reader.seek(startPosition); // 指定复制源文件的起始位置
				writer.seek(startPosition); // 指定复制目标文件的起始位置
				byte[] buff = new byte[bufferSize]; // 设置一个缓冲区

				while (startPosition < endPosition) { // 判断是否复制完成
					// 读操作
					int len = 0; // 已经读取的实际长度
					// 判断缓冲区是否读满
					if (startPosition + bufferSize < endPosition) {
						len = reader.read(buff); // 读满缓冲区
					} else {
						// 把剩余的填不满缓冲区的数据写入的缓冲区
						len = reader.read(buff, 0,
								(int) (endPosition - startPosition));
					}
					startPosition += len; // 起始位置(每读一次就发生变化)

					// 写操作
					writer.write(buff, 0, len); // 把缓冲区中的数据写入指定文件的指定区域

					// 输出提示信息
					System.out.println("线程" + (threadId + 1) + "下载: " + len
							+ "字节");
				}

				// 关闭资源
				reader.close();
				writer.close();
				System.out.println("线程" + (threadId + 1) + "下载完毕");

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

 

 

package dhcc.io;

public class MutiCopyFileDemo {
	public static void main(String[] args) {
		MutiCopyFileUtil copyFileUtil = new MutiCopyFileUtil("D:\\POI\\template\\3、新浪二手房登陆密码Js加密详解.mp4",
				"D:\\POI\\template\\test2.mp4", 3);

		// 开始复制   3   18.4    4  18.69   100  19.22   1000  20.57
		copyFileUtil.copyFile();
		
		
	}
}

当线程设置3个以后的时候,效率提升并不明显,因为这个时候cpu利用率一直都是100左右状态,没有提升空间。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值