一、前言:下面例子中,所有异常处理均采用抛出的形式,各位千万不要效仿

二、几种拷贝文件的方式

    2.1 字节流的形式

public static void byteCopy(String  sourcePath,String target) throws IOException {
	//1.创建输入流
	InputStream iStream = new FileInputStream(sourcePath);
	//2.创建输出流
	OutputStream oStream = new FileOutputStream(target);
	//3.一部分一部分读出
	byte[] bytes = new byte[10*1024];
	int br;//实际的读取长度
	while((br =iStream.read(bytes))!=-1) {//判断是否读到末尾
		oStream.write(bytes, 0, br);
	}
	//4.清空缓存
	oStream.flush();
	//5.关闭流
	if(iStream!=null) {
		iStream.close();
	}
	if(oStream!=null) {
		oStream.close();
	}
}

    2.2 字节流一次复制完成,缺点是:只能应用于小文件

public static void byteCopy2(String  sourcePath,String target) throws IOException {
	//1.创建输入流
	InputStream iStream = new FileInputStream(sourcePath);
	//2.创建输出流
	OutputStream oStream = new FileOutputStream(target);
	int len = iStream.available();
	//3.全部读出
	byte[] bytes = new byte[len];
	iStream.read(bytes);
	oStream.write(bytes, 0, len);
	//4.清空缓存
	oStream.flush();
	//5.关闭流
	if(iStream!=null) {
		iStream.close();
	}
	if(oStream!=null) {
		oStream.close();
	}
}

    2.3 带缓冲的字节流

public static void byteCopy3(String  sourcePath,String target) throws IOException {
	//1.创建输入流
	BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(sourcePath));
	//2.创建输出流
	BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(target),1024*1024);
	//3.一部分一部分读出
	byte[] bytes = new byte[10*1024];
	int br;//实际的读取长度
	while((br =bufferedInputStream.read(bytes))!=-1) {//判断是否读到末尾
		bufferedOutputStream.write(bytes, 0, br);
	}
	//4.清空缓存
	bufferedOutputStream.flush();
	//5.关闭流
	if(bufferedInputStream!=null) {
		bufferedInputStream.close();
	}
	if(bufferedOutputStream!=null) {
	    bufferedOutputStream.close();
	}
}

    2.4 字符流完成,缺点:不能指定字符集,不建议使用

public static void  CharCopy(String  sourcePath,String target) throws IOException{
	Reader reader = new FileReader(sourcePath);
	Writer writer = new FileWriter(target);
	char[] c = new char[10];
	int read;
	while((read = reader.read(c))!=-1) {
		writer.write(c, 0, read);
	}
	writer.flush();
	if(reader!=null) {
		reader.close();
	}
	if(writer!=null) {
		writer.close();
	}
}

    2.5 标准的字符流实现,能指定字符集,一行一行读出,true表示追加

public static void  CharCopy2(String  sourcePath,String target) throws IOException{
	BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(sourcePath), "utf-8"));
	PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(target,true),"utf-8"));
	String line;              
	while((line = bufferedReader.readLine())!=null) {
		printWriter.write(line+"\n");
	}
	if(bufferedReader != null) {
		bufferedReader.close();
	}
	if(printWriter != null) {
		printWriter.close();
	}
}

    2.6 NIO实现文件拷贝(用transferTo的实现 或者transferFrom的实现),这里是transferTo的实现。

public static void  NIOCopyFile(String  source,String target) throws  Exception{
    //1.采用RandomAccessFile双向通道完成,rw表示具有读写权限
    RandomAccessFile fromFile = new RandomAccessFile(source,"rw");
    FileChannel fromChannel = fromFile.getChannel();

    RandomAccessFile toFile = new RandomAccessFile(target,"rw");
    FileChannel toChannel = toFile.getChannel();

    long count =  fromChannel.size();
    while (count > 0) {
        long transferred = fromChannel.transferTo(fromChannel.position(), count, toChannel);
        count -= transferred;
    }
    if(fromFile!=null) {
        fromFile.close();
    }
    if(fromChannel!=null) {
        fromChannel.close();
    }
}

2.7 NIO实现文件自身内容拷贝(追加到末尾)

public static void main(String[] args)  throws Exception {
    //1.获取双向通道
    RandomAccessFile file = new RandomAccessFile("C:\\Users\\num11\\Desktop\\grade.txt","rw");
    //2.得到通道
    FileChannel channel = file.getChannel();
    //3.定义缓存
    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    if(channel.read(byteBuffer)!= -1){ //判断是否读到末尾
        //4.反转
        byteBuffer.flip();
        channel.write(byteBuffer);
        byteBuffer.clear();
    }
    if(file != null){
        file.close();
    }
}

2.8 java.nio.file.Files.copy()实现文件拷贝,其中第三个参数决定是否覆盖

public  static  void  copyFile(String  source,String target){
    Path sourcePath      = Paths.get(source);
    Path destinationPath = Paths.get(target);

    try {
        Files.copy(sourcePath, destinationPath,
                StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

三、总结

    以上方法中经过测试,NIO实现的方式的执行效率最高