一个疑问?多线程,NIO,普通IO复制同一个文件

多线程

CopyFile.java

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;

public class CopyFile implements Runnable {

	// 源文件
	private String source;

	// 目标文件
	private String target;

	// 分块总数
	private int blockCount;

	// 开始复制的块序号
	private int blockNo;

	// 缓存大小
	private int maxBuffSize = 1024 * 1024;

	/**
	 * 将source文件分blockCount块后的第blockNo块复制至source
	 * 
	 * @param source
	 *            源文件
	 * @param target
	 *            目标文件
	 * @param blockCount
	 *            文件分块copy数
	 * @param blockNo
	 *            开始copy的块序号
	 */

	public CopyFile(String source, String target, int blockCount, int blockNo) {
		this.source = source;
		this.target = target;
		this.blockCount = blockCount;
		this.blockNo = blockNo;
	}

	@Override
	public void run() {
		// 得到源文件
		File file = new File(source);

		// 得到源文件大小
		long size = file.length();

		// 根据文件大学及分块总数计算出单个块的大小
		long blockLength = size / blockCount;

		// 算出当前开始复制的位置
		long startPosition = blockLength * blockNo;

		// 实例化缓存
		byte[] buff = new byte[maxBuffSize];

		try {
			// 从源文件得到输入流
			InputStream in = new FileInputStream(source);

			// 得到目标文件的随机访问对象
			RandomAccessFile raf = new RandomAccessFile(target, "rw");

			// 将目标文件的指针偏移至开始位置
			raf.seek(startPosition);

			// 当前读取的字节数
			int curReadLength = 0;

			// 累计读取字节数的和
			int totalReadLength = 0;

			// 将源文件的指针偏移至开始位置
			in.skip(startPosition);

			// 依次分块读取文件
			while ((curReadLength = in.read(buff)) > 0 && totalReadLength < blockLength) {
				// 将缓存中的字节写入文件中
				raf.write(buff, 0, curReadLength);

				// 累计读取的字节数
				totalReadLength += curReadLength;

			}
			// 关闭相关资源
			raf.close();
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
ThreadTest.java

public class ThreadTest {

	// 源文件
	private static String source;

	// 目标文件
	private static String target;

	// 分块数
	private static int blockCount;

	public static void main(String[] args) {
		// 记录开始时间
		long beginTime = System.currentTimeMillis();
		source = "E:/BaiduNetdiskDownload/flashplayer_25_ax_debug_25.0.0.127.exe";
		target = "E:/多线程.exe";
		blockCount = 3;

		// 依次分块进行文件copy
		for (int i = 0; i <= blockCount; i++) {
			// 实例化文件复制对象
			CopyFile copyFile = new CopyFile(source, target, blockCount, i);

			// 实例化线程
			Thread th = new Thread(copyFile);

			th.start();

			try {
				th.join();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// 计算耗时
		long entTime = System.currentTimeMillis();

		// 输出耗时
		System.out.println("共用时:" + (entTime - beginTime) + "ms");
	}
}
耗时:


NIO方式复制

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;


/***
 * NIO方式复制文件
 * @param args
 */
public class NIOCopy {

	// 源文件
	private static String source;

	// 目标文件
	private static String target;

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		source = "E:/BaiduNetdiskDownload/flashplayer_25_ax_debug_25.0.0.127.exe";
		target = "E:/NIO.exe";

		File file = new File(source);

		File file2 = new File(target);

		long length = file.length();
		int i = 0;
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			in = new FileInputStream(file);
			out = new FileOutputStream(file2);
			FileChannel inC = in.getChannel();
			FileChannel outC = out.getChannel();
			while (true) {
				if (inC.position() == inC.size()) {
					outC.close();
					inC.close();
					break;
				}
				if ((inC.size() - inC.position()) < length)
					length = inC.size() - inC.position();
				inC.transferTo(inC.position(), length, outC);
				inC.position(inC.position() + length);
				i++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("共用时"+(end - start)+"ms");
	}
}
耗时:



普通复制:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CommonCopy {
	// 源文件
	private static String source;

	// 目标文件
	private static String target;

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		source = "E:/BaiduNetdiskDownload/flashplayer_25_ax_debug_25.0.0.127.exe";
		target = "E:/普通.exe";

		File file = new File(source);

		File file2 = new File(target);

		int length = (int)file.length();
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			in = new FileInputStream(file);
			out = new FileOutputStream(file2);
			byte[] buffer = new byte[length];
			int i = 0;
			while ((i = in.read(buffer)) != -1) {
					out.write(buffer, 0, length);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long end = System.currentTimeMillis();
		System.out.println("共用时"+(end - start)+"ms");
	}
}
耗时:


普通复制文件的方法不太稳定,今天跳到了1KMS,但是仍然比多线程快???

一个疑问:为什么运用多线程复制文件反而不如普通方法复制?????

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值