一個疑問?多線程,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,但是仍然比多線程快???

一個疑問:爲什麼運用多線程複製文件反而不如普通方法複製?????

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章