子线程复制文件,当主线程interrupt子线程时,若子线程还未完成文件的复制,则删除有已复制的文件
主线程
public static void main(String[] args) { //new 出复制文件的子线程 Thread copyThread = new Thread(new CopyFolderThread()); //开始子线程,让子线程处于runnable状态 copyThread.start(); try { //主线程暂停,等待子线程执行参数时间 copyThread.join(2 * 1000); }catch (InterruptedException e) { e.printStackTrace(); } //如果子线程还未执行结束,即copyThread.isAlive()=true,打断子线程(即提醒子线程停止复制并删除) if(copyThread.isAlive()) { copyThread.interrupt(); } }
调用文件复制的线程类
public class CopyFolderThread implements Runnable { public void run() { //要复制的文件 String srcDir = "G:/软件"; //要复制到的目录 String desDir = "e:"; String fileName = srcDir.substring(srcDir.lastIndexOf("/"),srcDir.length()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); File file = new File(srcDir); try { System.out.println(sdf.format(new Date()) + " start copy folder"); //调用文件复制方法,该方法可能抛出当前线程被中断异常 FileUtil.copyFolder(file, desDir); System.out.println(sdf.format(new Date()) + " copy folder success"); }catch(InterruptedException e) { //文件复制未完成,复制文件的线程被打断了,处理InterruptedException,删除已复制的文件 System.out.println(sdf.format(new Date()) + "start deal exception,delete folder"); File f = new File(desDir + "/" + fileName); //删除文件 FileUtil.deleFolder(f); } } }
用递归方法复制和删除文件的文件工具类
/** * 根据给定的文件,将其复制到给定的目录 * @param file 要复制的文件 * @param desDir 目标目录 */ public static void copyFolder(File file,String desDir) throws InterruptedException { if(!file.exists()) { System.out.println("文件不存在"); System.exit(1); } if(!file.isDirectory()) { FileInputStream fis = null; FileOutputStream fos = null; byte[] temp = new byte[1024]; int length = 0; File desFile = new File(desDir + "/" + file.getName()); try { fis = new FileInputStream(file); fos = new FileOutputStream(desFile); while((length=fis.read(temp)) != -1) { //判断复制文件的线程(即调用copyFolder方法的当前线程)是否被打断了,若打断抛出InterruptedException if(Thread.currentThread().isInterrupted()) { System.out.println("---------file copy thread interrupted"); throw new InterruptedException(); } fos.write(temp, 0, length); } fos.flush(); System.out.println(desDir+ "//" + file.getName() + "文件创建成功"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(fis != null) { try { fis.close(); //System.out.println("-----------fis已经关闭"); } catch (IOException e) { e.printStackTrace(); } } if(fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }else { File desFile = new File(desDir + "/" + file.getName()); if(!desFile.mkdirs()) { System.out.println("创建目录" + desDir + "/" + file.getName() + "出错,目录已存在或出现其他原因"); System.exit(1); } System.out.println(desDir+ "//" + file.getName() + "目录创建成功"); File[] childrenFiles = file.listFiles(); for(int i=0; i<childrenFiles.length; i++) { try { copyFolder(childrenFiles[i],desFile.getCanonicalPath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 删除给定目录下的文件 * @param file 要删除的文件 */ public static void deleFolder(File file) { if(!file.exists()) { System.out.println("文件夹不存在"); System.exit(1); } File[] childrenFiles = file.listFiles(); //先删除子文件 if(childrenFiles != null) { for(int i=0; i<childrenFiles.length; i++) { deleFolder(childrenFiles[i]); } } //再删除父目录 if(file.exists()) { file.delete(); } System.out.println(file.getName() + "已被删除"); }
小结:
1、Thread.interrupt()拿上文的实现做解释,当主线程main调用copyThread.interrupt方法时,只是主线程对copyThread子线程作出了一个提醒,提醒让其停止文件的复制并删除;copyThread可对这一提醒作出响应(通过catch InterruptedException),也可对这一提醒不做任何响应。
2、Thread.interrupted()和Thread.isInterrupted()方法均返回当前线程是否被中断的信息,区别在于interrupted()会改变状态位,而isInterrupted()方法不改变其状态位
3、让文件复制工具在更小的粒度上去检查当前线程是否被中断会更具现实意义。