java_多线程复制文件夹(拷贝目录):真.多线程(为每个文件分配一个复制线程)

package experiment10.exp1;
import experiment9.FileName;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* @Author xuchaoxin
* @Date 12/19/2020 9:41 AM
* @Version 1.0
*/
public class CreatCopyPathThreads {
static int count = 0;
static List<Thread> list = new ArrayList<>();//存储线程对象.
/*本递归复制函数具有检查并创建新目录的能力,*/
/**
* @param srcPath 可能是个目录,也可能是个文件
* @param desPath 当srcPath 是一个目录的时候,desPath也必须是一个目录(1.约定该参数和srcPath是相同尾缀时;2.不用关心尾缀
* 可能的参数组合包括:dir->dir;file->file;file->dir;(不可能是dir->file)
* @throws IOException
* @throws InterruptedException
*/
static void createCopyPathThreads(String srcPath, String desPath) throws IOException, InterruptedException {
// System.out.println(count++);//testing(通过中途的内部打印来监视count的累计情况.)
File srcPathFile = new File(srcPath);
File desPathFile = new File(desPath);
/* 如果源目标是个目录,则要保证目标目录存在: */
// if (srcPathFile.isDirectory()&&!(new File(desPath)).exists()) {
// (new File(desPath)).mkdir();//创建目录
// }
/*分析源路径*/
if (srcPathFile.isDirectory()) {
//确保对应的目标目录存在
if (!(new File(desPath)).exists()) {
desPathFile.mkdir();//创建目录
}
/*遍历当前目录下的子目录和文件(即各个条目)*/
String[] filesPathString = srcPathFile.list();
for (String subItem : filesPathString) {
String absoluteSrcSubItemStr = srcPath + File.separator + subItem;
String absoluteDesSubItemStr = desPath + File.separator + subItem;
//
// File subItemFile = new File(absoluteSrcSubItemStr);
// File desSubItemFile = new File(absoluteDesSubItemStr);
/*直接递归:*/
createCopyPathThreads(absoluteSrcSubItemStr, absoluteDesSubItemStr);
}//endFor
}//end if
else {
Thread thread = new Thread(() -> {
if (!desPathFile.exists()) {
try {
//复制file
Files.copy(srcPathFile.toPath(), desPathFile.toPath());
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.setName("threadNo" + count++);
list.add(thread);
}
//System.out.println("The replication operation has been successfully executed!");
}//endCopyFunction
public static int getCount() {
return count = list.size();
}
/**
* //todo 相应而生的策略:先创建所有需要创建的进程,然后统一start;就解决了线程数的统计问题(统一join,就解决了时间统计的问题)(而且不会退化为单线程排队执行.)可以发现,进程的创建和执行不是绑在一起的,而是通过start方法才会启动.可见其用处(灵活)
* @param srcPath
* @param desPath
* @throws InterruptedException
*/
public static void copyPath(String srcPath, String desPath) throws InterruptedException, IOException {
createCopyPathThreads(srcPath, desPath);
for (Thread thread : list) {
thread.start();
}
for (Thread thread : list) {
thread.join();
}
}
//test the class
public static void main(String[] args) throws IOException, InterruptedException {
//计时开始.
long startTime = System.currentTimeMillis();
//一句话,实现一个需求:
copyPath(FileName.fileName11_1, "D:/src");
System.out.println("共启用了" + CreatCopyPathThreads.getCount() + "个线程");
System.out.println("目录拷贝完成,共耗时" + (System.currentTimeMillis() - startTime) + "毫秒");
}
}//end class
posted @   xuchaoxin1375  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2021-10-08 微信小程序_学习入门日志(2022阅读官方参考文档和基础开发指南教程/appid问题)guide for beginner
点击右上角即可分享
微信分享提示