基于输入输出流、递归遍历、File类
实现目录拷贝,将一个目录拷贝到另一个目录,考虑子文件的情况(子文件应一起拷贝)
public class FileTools {
/**
* 将目标File对象关联的本地文件(或者目录)拷贝到目标目录中
* @param source 需要被拷贝File关联的文件(或目录)
* @param targetDir 目标目录
*/
public static void copy(File source,File targetDir) {
//判断源文件是否是标准文件
if(source.isFile()) {
//如果源文件是标准文件,则直接进行文件拷贝
copyFile(source, targetDir);
}else {
//在目标目录下创建一个跟源目录同名的子目录(未创建)
targetDir = new File(targetDir,source.getName());
//如果目标目录不存在则创建
if(!targetDir.exists()) {
targetDir.mkdirs();
}
//获取源目录下所有的子文件
File[] subFiles = source.listFiles();
if(subFiles != null) {
//遍历所有的子文件(File)
for(int i = 0;i<subFiles.length;i++) {
copy(subFiles[i],targetDir);
}
}
}
}
/**
* 将传入的源文件(标准文件)拷贝到指定的目录中
* @param sourceFile 源文件对象
* @param targetDir 目标目录对象
*/
private static void copyFile(File sourceFile,File targetDir) {
//判断目标目录是否存在,若不存在创建
if(!targetDir.exists()) {
targetDir.mkdirs();
}
//根据提供的源文件文件名,结合目标目录构建一个目标文件对象
File target = new File(targetDir,sourceFile.getName());
InputStream is = null;
OutputStream os = null;
try {
//获取源文件的输入流
is = new FileInputStream(sourceFile);
//获取目标文件的输出流
os = new FileOutputStream(target);
//声明字节缓冲区
byte[] b = new byte[1024];
//声明临时变量标记当前读取的实际字节数
int len = 0;
System.out.println("开始拷贝...");
while((len = is.read(b)) != -1) {
//使用输出流将数组从0开始写入len个字节到目标文件
os.write(b, 0, len);
}
System.out.println("拷贝完成!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(Objects.nonNull(os)) {
os.close();
}
if(Objects.nonNull(is)) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
File source = new File("源文件地址");
File targetDir = new File("目标文件地址");
copy(source,targetDir);
}
}
实现复制:
声明字节缓冲区,循环读取字节存入缓冲区,然后再将缓冲区的数据写入。
核心代码如下:
//声明字节缓冲区
byte[] b = new byte[1024];
int len = 0;
//循环读取字节并存入缓冲区
while ((len = fis.read(b)) != -1) {
fos.write(b,0,len);
}