目录
目的:
将原文件夹下所有的文件夹及文件复制到目标文件夹下。
原文件夹及目录
目标路径
思路:
想象遍历整个文件夹,取到最根的文件时,先创建目录,再拷贝对应文件。
实现步骤:
0、创建执行类,在主函数中,确定要拷贝的文件夹及目标文件夹。
public class CopyDemo2 {
public static void main(String[] args) {
//要拷贝的文件夹
String srcDirectName = "D://Mysql";
//目标文件夹
String targetDirectName = "D:" + File.separator + "测试文件夹";
//封装成File对象
File srcFile = new File(srcDirectName);
File targetDirectory = new File(targetDirectName);
}
}
1、编写拷贝函数,先写到遍历文件夹,能索引到最根文件
//拷贝多级文件夹函数
public static void copyDirect(File srcFile,File targetDirectory)
{
//遍历文件夹,要求能取到最根的文件(遍历次数到了即可,先不用写取到文件的代码)
if (srcFile.isDirectory()&&srcFile.exists())
{
File[] files = srcFile.listFiles();
for (File temp:files)
{
copyDirect(temp,targetDirectory);
}
}
}
2、在拷贝函数中,增加取到文件时的逻辑,接下来编写创建文件夹的函数和拷贝文件的函数,最后回头补充即可。
public static void copyDirect(File srcFile,File targetDirectory)
{
//取到文件的逻辑
if (srcFile.isFile())
{
//TODO 调用创建文件夹的函数
//TODO 调用创建文件的函数
}
//遍历文件夹,要求能取到最根的文件(遍历次数到了即可,先不用写取到文件的代码)
if (srcFile.isDirectory()&&srcFile.exists())
{
File[] files = srcFile.listFiles();
for (File temp:files)
{
copyDirect(temp,targetDirectory);
}
}
3、编写创建文件夹的函数
//创建文件夹的函数
public static void createDirect(File file)
{
if (!file.exists())
{
file.mkdirs();
}
}
4、编写拷贝文件的函数
//拷贝文件的函数
public static void copyFile(File srcFile,File targetDirectory) throws IOException {
FileInputStream fileInputStream=null;
FileOutputStream fileOutputStream=null;
try {
fileInputStream=new FileInputStream(srcFile);
fileOutputStream=new FileOutputStream(targetDirectory);
byte[] bytes=new byte[1024];
int length;
while((length=fileInputStream.read(bytes))!=-1)
{
fileOutputStream.write(bytes,0,length);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (fileInputStream!=null) fileInputStream.close();
if (fileOutputStream!=null) fileOutputStream.close();
}
}
5、回到步骤2,完善调用部分
//拷贝多级文件夹函数
public static void copyDirect(File srcFile,File targetDirectory) throws IOException {
if (srcFile.isFile())
{
//1、创建文件所在的目录
//封装正确的路径(思路是替换掉文件路径最前面的顶级目录)
String trueDirect= targetDirectory.getAbsolutePath()+srcFile.getParent().substring(8);
//调用函数
createDirect(new File(trueDirect));
//2、拷贝文件
//调用文件拷贝方法前,需要先处理文件的路径((思路依旧是替换掉文件路径最前面的顶级目录))
String tureFile= targetDirectory+srcFile.getAbsolutePath().substring(8);
copyFile(srcFile,new File(tureFile));
}
if (srcFile.isDirectory()&&srcFile.exists())
{
File[] files = srcFile.listFiles();
for (File temp:files)
{
copyDirect(temp,targetDirectory);
}
}
}
6、完善主函数的调用
public class CopyDemo2 {
public static void main(String[] args) {
//要拷贝的文件夹
String srcDirectName = "D://Mysql";
//目标文件夹
String targetDirectName = "D:" + File.separator + "测试文件夹";
//封装成File对象
File srcFile = new File(srcDirectName);
File targetDirectory = new File(targetDirectName);
//调用拷贝多级文件的方法
try {
copyDirect(srcFile,targetDirectory);
} catch (IOException e) {
System.out.println("拷贝文件失败");
throw new RuntimeException(e);
}
}
}
完整代码:
package com.demo.filedemo;
import java.io.*;
public class CopyDemo2 {
public static void main(String[] args) {
//要拷贝的文件夹
String srcDirectName = "D://Mysql";
//目标文件夹
String targetDirectName = "D:" + File.separator + "测试文件夹";
//封装成File对象
File srcFile = new File(srcDirectName);
File targetDirectory = new File(targetDirectName);
//调用拷贝多级文件的方法
try {
copyDirect(srcFile, targetDirectory);
} catch (IOException e) {
System.out.println("拷贝文件失败");
throw new RuntimeException(e);
}
}
//拷贝多级文件夹函数
public static void copyDirect(File srcFile,File targetDirectory) throws IOException {
if (srcFile.isFile())
{
//1、创建文件所在的目录
//封装正确的路径(思路是替换掉文件路径最前面的顶级目录)
String trueDirect= targetDirectory.getAbsolutePath()+srcFile.getParent().substring(8);
//调用函数
createDirect(new File(trueDirect));
//2、拷贝文件
//调用文件拷贝方法前,需要先处理文件的路径((思路依旧是替换掉文件路径最前面的顶级目录))
String tureFile= targetDirectory+srcFile.getAbsolutePath().substring(8);
copyFile(srcFile,new File(tureFile));
}
if (srcFile.isDirectory()&&srcFile.exists())
{
File[] files = srcFile.listFiles();
for (File temp:files)
{
copyDirect(temp,targetDirectory);
}
}
}
//创建文件夹的函数
public static void createDirect(File file)
{
if (!file.exists())
{
file.mkdirs();
}
}
//拷贝文件的函数
public static void copyFile(File srcFile,File targetDirectory) throws IOException {
FileInputStream fileInputStream=null;
FileOutputStream fileOutputStream=null;
try {
fileInputStream=new FileInputStream(srcFile);
fileOutputStream=new FileOutputStream(targetDirectory);
byte[] bytes=new byte[1024];
int length;
while((length=fileInputStream.read(bytes))!=-1)
{
fileOutputStream.write(bytes,0,length);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (fileInputStream!=null) fileInputStream.close();
if (fileOutputStream!=null) fileOutputStream.close();
}
}
}
结果:
比较目录结构及子文件夹、子文件
优化点:
一、调用创建目录和创建文件的截取部分写死
方案:修改拷贝多级文件的函数,在调用前计算目录替换部分的长度并传入(下三图为拷贝多级文件的函数、调用拷贝函数、转换长度部分)
二、未复制空文件夹
方案:第一步索引到最根文件时,增加判断文件夹下级是否为空的逻辑。
其中,if的判断条件不可用files==null,因为即使文件夹下的文件为null,listFiles()方法依旧会返回一个对象,而非空引用。