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

来源:互联网 发布:网络监控手机客户端 编辑:程序博客网 时间:2024/05/22 15:59

多线程

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;}@Overridepublic 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;// 依次分块进行文件copyfor (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,但是仍然比多线程快???

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

原创粉丝点击