java使用IO流完成文件的复制(文本、图片、视频)

本文介绍如何使用字节流和字符流高效复制文件,并逐步优化代码,包括利用缓冲区和缓冲流来提升复制速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、使用字节流实现

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

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)


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值