一、使用字节流实现

复制文件中的地址可以是图片或视频。

1.基础版

package com.uwo9.test01;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		// 被复制的文件
		File fromFile = new File("E:/Temp/1.jpg");
		// 复制出来的文件
		File toFile = new File("E:/Temp/2.jpg");
		// 声明入流
		InputStream is = null;
		//
		OutputStream os=null;
		try {
			is = new FileInputStream(fromFile);//创建输入流
			os = new FileOutputStream(toFile);// 创建输出流
			// 逐个字节读取
			int content = is.read();
			while (content != -1) {
				// System.out.print((char)content); 控制台
				// 使用输出流将读取到的content写入文件
				os.write(content);
				// 刷新流
				// os.flush();
				content = is.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			// 关闭流
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			long endTime = System.currentTimeMillis();
			long costTime = endTime - startTime;
			System.out.println("复制文件完成,耗时:" + costTime + "毫秒");
		}
		
		
	}

}

发现问题:我们发现,上面的方法,可以实现复制功能,但复制的文件比较大时,复制比较慢


2.第一次优化

我们可以用字节数组来做缓冲区,提升效率。

package com.uwo9.test01;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		// 被复制的文件
		File fromFile = new File("E:/Temp/1.avi");
		// 复制出来的文件
		File toFile = new File("E:/Temp/2.avi");
		// 声明入流
		InputStream is = null;
		//
		OutputStream os = null;
		try {
			is = new FileInputStream(fromFile);// 创建输入流
			os = new FileOutputStream(toFile);// 创建输出流
			// 创建用来做缓冲区的字节数组
			byte[] array = new byte[512];
			// 将数组读取到array中,count记录的为读取数组中字节数
			int count = is.read(array);
			while (count != -1) {
				// 使用输出流将读取到的content写入文件
				// os.write(array);
				// 将读取到的有效数据写入文件
				os.write(array, 0, count);
				// 刷新流
				// os.flush();
				count = is.read(array);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭流
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			long endTime = System.currentTimeMillis();
			long costTime = endTime - startTime;
			System.out.println("复制文件完成,耗时:" + costTime + "毫秒");
		}

	}

}

发现问题:效率提升了,但我们java里是否有更好的实现方法呢

3.第二次优化

我们可以加入缓冲字符流


节点流与处理流(包装流):


1.节点流:可以直接从数据源或目的地读写数据。节点流处于IO操作的第一线,所有操作必须通过他们进行。


2.处理流:不能直接连接到数据源或目的地,是其他流进行封装。目的是主要是简化操作和提高性能。处理流可以对其他流进行处理(提高效率或操作灵活性)。

package com.uwo9.test01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		File fromFile = new File("E:/Temp/1.avi");
		File toFile = new File("E:/Temp/2.avi");
		InputStream is = null;
		OutputStream os = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			is = new FileInputStream(fromFile);
			os = new FileOutputStream(toFile);
			// 创建缓冲流
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(os);
			int content = bis.read();
			while (content != -1) {
				// 使用缓冲流写数据
				bos.write(content);
				// 刷新
				bos.flush();
				content = bis.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		long endTime = System.currentTimeMillis();
		System.out.println("视频复制完成,耗时:" + (endTime - startTime) + "毫秒");

	}

}

发现问题:我们还想继续提升效率

4.第三次优化:

我们可以在缓冲流的基础上再加字节数组来做缓冲区,提升效率

package com.uwo9.test01;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		File fromFile = new File("E:/Temp/1.avi");
		File toFile = new File("E:/Temp/2.avi");
		InputStream is = null;
		OutputStream os = null;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			is = new FileInputStream(fromFile);
			os = new FileOutputStream(toFile);
			// 创建缓冲流
			bis = new BufferedInputStream(is);
			bos = new BufferedOutputStream(os);
			byte[]buffer = new byte[8192];
			int count = bis.read(buffer);
			while(count != -1){
				//使用缓冲流写数据
				bos.write(buffer,0,count);
				//刷新
				bos.flush();
				count = bis.read(buffer);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		long endTime = System.currentTimeMillis();
		System.out.println("视频复制完成,耗时:" + (endTime - startTime) + "毫秒");

	}

}

我们会发现,效率再次大大提升。

二、使用字符流

1.基础版

package com.uwo9.test01;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		//1.创建文件对象
		File fromFile = new File("E:/Temp/Test1.java");
		File toFile = new File("E:/Temp/Test2.java");
		//2.创建字符输入流
		Reader reader=null;
		Writer writer=null;
		try {
			reader = new FileReader(fromFile);
			writer = new FileWriter(toFile);
			//3.循环读取(打印)
			int content = reader.read();
			while(content != -1){
				//将字符写入文件
				writer.write(content);
				//继续读取
				content = reader.read();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//4.关闭流
			try {
				reader.close();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long endTime = System.currentTimeMillis();
		System.out.println("复制完成,耗时:"+(endTime-startTime)+"毫秒");
		
		

	}

}



发现问题:我们发现,字符流复制二进制普通文本类型的文件没问题,但读取图片、视频文件时,会出现丢帧、文件损坏现象。

2.优化普通二进制文本文件方法

我们可以使用包装流(处理流),及其特有的逐行读取方法提升效率

package com.uwo9.test01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class Test08 {

	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		File fromFile = new File("E:/Temp/Test1.java");
		File toFile = new File("E:/Temp/Test1.java");
		Reader reader = null;
		Writer writer = null;
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {
			reader = new FileReader(fromFile);
			writer = new FileWriter(toFile);
			br = new BufferedReader(reader);
			bw = new BufferedWriter(writer);
			String content = br.readLine();//读取一行
			while (content != null) {
				bw.write(content);
				// 换行操作
				bw.newLine();
				bw.flush();
				content = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		long endTime = System.currentTimeMillis();
		System.out.println("文件复制完成,耗时:" + (endTime - startTime) + "毫秒");

	}

}




FileWriter(File file, boolean append)

FileOutputStream(File file, boolean append)