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("源文件不存在, 拷贝失败");
}
}
注意, 代码问题
- 在开发里面尽量不要使用 do … while 循环, 要使用 while 循环
- 拷贝的速度堪忧。
第一次改进内容
// 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);
}
以上的方式还是针对于一个字节的模式完成的, 实际之中如果文件太大, 这种做法一定不可取。
第二次改进: 解决读取慢的问题
如果要解决读取慢的问题, 那么就需要加大一个缓存, 也就是说一次性读取多个字节数据, 那么就要开辟一个字节数组
核心代码
//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) + "毫秒");
}
==如果现在要求处理的数据都在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("源文件不存在, 拷贝失败");
}
}
下一篇: 关于扫条码的问题