java文件复制和文件夹复制涉及到java.lang.io类中的字节流类:InputStream和OutputStream。
这两个类都是抽象类,这就要使用它们的子类,文件操作涉及的子类为FileInputStream和FileOutputStream。
先讲文件复制:
方案有两个:
方案一:一次将文件的所有内容读出,再将读出的内容写入至目标文件中;(pass)
方案二:一次只读部分内容,一次一次的将读出的内容写入目标文件中;
看代码:
package com.jemmy.main;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
class FileUtil{
private File srcFile; //源文件路径
private File desFile; //目的文件路径
/**
* 构造函数,有参
* @param srcFile
* @param desFile
*/
public FileUtil(String srcFilePath, String desFilePath){
this(new File(srcFilePath), new File(desFilePath));
}
public FileUtil(File srcFile, File desFile) {
this.srcFile = srcFile;
this.desFile = desFile;
}
/**
* 文件复制实现
* @param srcFile
* @param desFile
* @return
* @throws Exception
*/
public boolean copyImpl(File srcFile, File desFile)throws Exception{
if (!desFile.getParentFile().exists()){ //如果父路径不存在
desFile.getParentFile().mkdirs(); //创建父路径
}
InputStream in = null;
OutputStream out = null;
try{
in = new FileInputStream(srcFile);
out = new FileOutputStream(desFile);
byte [] data = new byte[1024];
int len = 0;
while((len = in.read(data)) != -1){
out.write(data, 0, len);
}
return true;
}catch(Exception e){
throw e;
}finally{
if (in != null){
in.close();
}
if (out != null){
out.close();
}
}
}
public boolean copy() throws Exception{
if (!this.srcFile.exists()){
System.out.println("源文件不存在!");
return false;
}
System.out.println(this.desFile);
return this.copyImpl(srcFile, this.desFile);
}
}
public class FileCopy {
public static void main(String[] args) throws Exception {
//如果参数不正确,程序退出
if (args.length != 2){
System.out.println("函数调用错误,正确的使用方式是:java fileCopy 源文件路径 目的文件路径");
System.exit(-1);
}
FileUtil fu = new FileUtil(args[0], args[1]);
long start = System.currentTimeMillis();
System.out.println(fu.copy()? "复制成功" : "复制失败");
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
}
关键代码分析:这个地方一定要这么写,否则,如果目标文件路径如:d:\newdir\newdir\newdir\hello.text这样时,会报找不到路径的错误。
if (!desFile.getParentFile().exists()){ //如果父路径不存在
desFile.getParentFile().mkdirs(); //创建父路径
}
测试代码:
public static void main(String[] args) throws Exception {
//如果参数不正确,程序退出
if (args.length != 2){
System.out.println("函数调用错误,正确的使用方式是:java fileCopy 源文件路径 目的文件路径");
System.exit(-1);
}
FileUtil fu = new FileUtil(args[0], args[1]);
long start = System.currentTimeMillis();
System.out.println(fu.copy()? "复制成功" : "复制失败");
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
文件夹复制
文件夹复制需要注意两个地方:
1、递归调用
2、目标文件路径生成
看代码:
public boolean copyDir() throws Exception{
return copyDirImpl(this.srcFile);
}
/**
* 拷贝目录实现
* @param file
* @return
* @throws Exception
*/
public boolean copyDirImpl(File file) throws Exception{
//如果是目录,则递归
if (file.isDirectory()){
File result[] = file.listFiles();
if (result != null){
for(int i = 0 ; i < result.length; i++){
copyDirImpl(result[i]);
}
}
}else{ //如果是文件,则复制文件,复制文件之前先构造目的文件对象
File newFile = new File(this.desFile, file.getPath().replace(this.srcFile.getPath() + File.separator, ""));
copyImpl(file, newFile);
}
return true;
}
关键代码1:
for(int i = 0 ; i < result.length; i++){
copyDirImpl(result[i]);
}
递归调用,若果源文件是目录的时候,则进行递归调用;
关键代码2:
File newFile = new File(this.desFile, file.getPath().replace(this.srcFile.getPath() + File.separator, ""));
创建目标文件操作对象,file.getPath()获取到的是源文件的路径,需要讲源文件的路劲替换成新文件的路径。File.separator为路径中“\“,在window中为\,但是在unix系统中则为/,使用File.separator则会调用FileSystem函数,由JVM判断当前是什么系统,然后选择到底使用\, 还是/,这是一种兼容性操作,推荐使用,如路径:d:\test\hello.text可以表示为:"d:" + File.separator + "test" + File.separator + "hello.text";虽然有点麻烦,但是体现了Write One, Run Everywhere的编程思想。
测试:
public static void main(String[] args) throws Exception {
//如果参数不正确,程序退出
if (args.length != 2){
System.out.println("函数调用错误,正确的使用方式是:java fileCopy 源文件路径 目的文件路径");
System.exit(-1);
}
FileUtil fu = new FileUtil(args[0], args[1]);
long start = System.currentTimeMillis();
System.out.println(fu.copyDir()? "复制成功" : "复制失败");
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}