欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 实现文件拷贝

程序员文章站 2024-01-18 19:37:04
...

案例: 原始实现, 未优化

package com.cwq.beyond;

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

/**
 * 建立一个专门负责文件拷贝处理的类, 该类具备如下功能: 
 * 1. 需要判断拷贝的源文件是否存在
 * 2. 需要判断目标文件父路径是否存在, 如果不存在则应该创建
 * 3. 需要进行文件拷贝操作的处理
 * @author DHL
 *
 */
class CopyUtil{  // 这个类不需要任何的属性, 所以建议将构造方法私有化,使用 static 方法
	private CopyUtil() {}  // 将构造方法私有化
	/**
	 *  判断要拷贝的源路径是否存在
	 * @param path	输入的源路径信息
	 * @return 如果该路径真实存在, 返回 true , 否则返回 false
	 */
	public static boolean fileExists(String path) {
		return new File(path).exists();
	}
	
	public static void createParentDirectory(String path) {
		File file = new File(path);
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
	}
	
	/**
	 * 实现文件拷贝的操作处理
	 * @param srcPath 源文件路径
	 * @param desPath 目标文件路径
	 * @return 拷贝完成返回 true 否则返回false
	 */
	public static boolean copy(String srcPath, String desPath) {
		boolean flag = false;
		File inFile = new File(srcPath);
		File outFile = new File(desPath);
		InputStream input = null;
		OutputStream output = null;
		try {
			input = new FileInputStream(inFile);
			output = new FileOutputStream(outFile);
			copyHandle(input, output);
			flag = true;  // 如果没有发生异常, 则一定会执行此语句
		} catch (Exception e) {
			flag = false;
		} finally {
			try {
				input.close();
				output.close();
			} catch (Exception e2) { }
		}
		return flag;
	}
	
	private static void copyHandle(InputStream input, OutputStream output) throws IOException {
		long start = System.currentTimeMillis();
		// InputStream 有一个读取单个字节的方法: int read();
		// OutputStream 有一个输出单个字节的方法: void write(int data)
		int temp = 0;
		do {
			temp = input.read();  // 读取单个字节数据
			output.write(temp);
		}while(temp != -1);  // 如果数据继续读取
		long end = System.currentTimeMillis();
		System.out.println("[统计]拷贝文件所花费的时间为 :"+ (end-start) + "毫秒");
	}
	
}

public class Copy {
	public static void main(String[] args) {
		if (args.length != 2) { // 现在的参数不是两个
			System.out.println("错误的执行方式, 命令调用: java Copy 源文件路径 目标文件路径");
			System.exit(1); // 系统退出
		} 
		if(CopyUtil.fileExists(args[0])) {  // 必须要判断要拷贝的源文件必须存在
			CopyUtil.createParentDirectory(args[1]);  // 创建目标的父目录
			System.out.println(CopyUtil.copy(args[0],args[1]) ? "文件拷贝成功~" : "拷贝失败!");
		}else
			System.out.println("源文件不存在, 拷贝失败");
		
	}
}

Java 实现文件拷贝

注意, 代码问题

  1. 在开发里面尽量不要使用 do … while 循环, 要使用 while 循环
  2. 拷贝的速度堪忧。

第一次改进内容

//		do {
//			temp = input.read();  // 读取单个字节数据
//			output.write(temp);
//		}while(temp != -1);  // 如果数据继续读取
		
		//1. temp = input.read(), 表示读取输入流中的一个字节
		//2. (temp = input.read()) != -1, 判断这个读取后的字节(保存在temp)是否为 -1, 如果不是表示有内容
		while ((temp = input.read()) != -1) {
			output.write(temp);
		}

Java 实现文件拷贝
以上的方式还是针对于一个字节的模式完成的, 实际之中如果文件太大, 这种做法一定不可取。

第二次改进: 解决读取慢的问题

如果要解决读取慢的问题, 那么就需要加大一个缓存, 也就是说一次性读取多个字节数据, 那么就要开辟一个字节数组

核心代码

	//1. temp = input.read(), 表示将数据读取到字节数组之中, 而后返回数据读取个数
		//2. (temp = input.read()) != -1, 判断这个数组的读取个数是否为 -1, 如果不是表示有内容
		while ((temp = input.read(data)) != -1) {
			output.write(data,0,temp);  // 输出读取到的部分字节数组
		}
		

方法代码, 以后使用最多的形式

private static void copyHandle(InputStream input, OutputStream output) throws IOException {
		long start = System.currentTimeMillis();
		// InputStream 有一个读取单个字节的方法: int read();
		// OutputStream 有一个输出单个字节的方法: void write(int data)
		int temp = 0;
		byte data [] = new byte[2048];
		
		
		
//		do {
//			temp = input.read();  // 读取单个字节数据
//			output.write(temp);
//		}while(temp != -1);  // 如果数据继续读取
		
		//1. temp = input.read(), 表示将数据读取到字节数组之中, 而后返回数据读取个数
		//2. (temp = input.read()) != -1, 判断这个数组的读取个数是否为 -1, 如果不是表示有内容
		while ((temp = input.read(data)) != -1) {
			output.write(data,0,temp);  // 输出读取到的部分字节数组
		}
		
		long end = System.currentTimeMillis();
		System.out.println("拷贝文件所花费的时间为 :"+ (end-start) + "毫秒");
	}

Java 实现文件拷贝
==如果现在要求处理的数据都在InputStream里面输出, 就采用以上的模型 ==

源码

package com.cwq.beyond;

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

/**
 * 建立一个专门负责文件拷贝处理的类, 该类具备如下功能: 
 * 1. 需要判断拷贝的源文件是否存在
 * 2. 需要判断目标文件父路径是否存在, 如果不存在则应该创建
 * 3. 需要进行文件拷贝操作的处理
 * @author DHL
 *
 */
class CopyUtil{  // 这个类不需要任何的属性, 所以建议将构造方法私有化,使用 static 方法
	private CopyUtil() {}  // 将构造方法私有化
	/**
	 *  判断要拷贝的源路径是否存在
	 * @param path	输入的源路径信息
	 * @return 如果该路径真实存在, 返回 true , 否则返回 false
	 */
	public static boolean fileExists(String path) {
		return new File(path).exists();
	}
	
	public static void createParentDirectory(String path) {
		File file = new File(path);
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
	}
	
	/**
	 * 实现文件拷贝的操作处理
	 * @param srcPath 源文件路径
	 * @param desPath 目标文件路径
	 * @return 拷贝完成返回 true 否则返回false
	 */
	public static boolean copy(String srcPath, String desPath) {
		boolean flag = false;
		File inFile = new File(srcPath);
		File outFile = new File(desPath);
		InputStream input = null;
		OutputStream output = null;
		try {
			input = new FileInputStream(inFile);
			output = new FileOutputStream(outFile);
			copyHandle(input, output);
			flag = true;  // 如果没有发生异常, 则一定会执行此语句
		} catch (Exception e) {
			flag = false;
		} finally {
			try {
				input.close();
				output.close();
			} catch (IOException e2) { }
		}
		return flag;
	}
	
	private static void copyHandle(InputStream input, OutputStream output) throws IOException {
		long start = System.currentTimeMillis();
		// InputStream 有一个读取单个字节的方法: int read();
		// OutputStream 有一个输出单个字节的方法: void write(int data)
		int temp = 0;
		byte data [] = new byte[2048];
		
		
		
//		do {
//			temp = input.read();  // 读取单个字节数据
//			output.write(temp);
//		}while(temp != -1);  // 如果数据继续读取
		
		//1. temp = input.read(), 表示将数据读取到字节数组之中, 而后返回数据读取个数
		//2. (temp = input.read()) != -1, 判断这个数组的读取个数是否为 -1, 如果不是表示有内容
		while ((temp = input.read(data)) != -1) {
			output.write(data,0,temp);  // 输出读取到的部分字节数组
		}
		
		long end = System.currentTimeMillis();
		System.out.println("拷贝文件所花费的时间为 :"+ (end-start) + "毫秒");
	}
	
}

public class Copy {
	public static void main(String[] args) {
		if (args.length != 2) { // 现在的参数不是两个
			System.out.println("错误的执行方式, 命令调用: java Copy 源文件路径 目标文件路径");
			System.exit(1); // 系统退出
		} 
		if(CopyUtil.fileExists(args[0])) {  // 必须要判断要拷贝的源文件必须存在
			CopyUtil.createParentDirectory(args[1]);  // 创建目标的父目录
			System.out.println(CopyUtil.copy(args[0],args[1]) ? "文件拷贝成功~" : "拷贝失败!");
		}else
			System.out.println("源文件不存在, 拷贝失败");
		
	}
}