写一个小工具,需求是从一个文件夹中搜索指定关键字的文件,并将搜索结果复制或者移动到新的目录下,需要保持原目录结构,并且关键字可灵活指定,并且可以指定是复制还是移动

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Scanner;

public class TextCopyUtil {
	static int countFiles = 0;// 声明统计文件个数的变量
	static int countFolders = 0;// 声明统计文件夹的变量

	static String srcFolderPath = "D:\\\\快盘";// 默认目录
	static String destFolderPath = "D:\\\\1360Downloads";// 目标目录
	static String keyword = "会议纪要.txt";
	static String type = "copy";
	
	public static void main(String[] args) {// java程序的主入口处
		System.out.println("现在开始操作批量处理文件");
		System.out.println("你要处理的文件为:"+args[0]);
		List<String> result = txt2StringList(new File(args[0]));
		
		System.out.print("\t默认目录");
		System.out.print("\t目标目录");
		System.out.print("\t关键字");
		System.out.println("\t处理方式(move表示移动,copy表示复制)");
		
		for (String string : result) {
			String[] arr = string.split("\t");
			String srcFolderPath = arr[0];// 默认目录
			String destFolderPath = arr[1];// 目标目录
			String keyword = arr[2];
			String type = arr[3];
			
			System.out.print("\t"+srcFolderPath);
			System.out.print("\t"+destFolderPath);
			System.out.print("\t"+keyword);
			System.out.println("\t"+type);
			
			Scanner input = new Scanner(System.in);
			System.out.println("如果和预期一致请输入数字1,否则其他数字");
				String name = input.nextLine();
				if("1".equals(name)){
					System.out.println(Calendar.getInstance().getTimeInMillis());
					run(srcFolderPath, destFolderPath, keyword, type);
					System.out.println(Calendar.getInstance().getTimeInMillis());
				}
			}
		}
	
	public static List<String> txt2StringList(File file) {
		List<String> result = new ArrayList<String>();
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));// 构造一个BufferedReader类来读取文件
			String s = null;
			while ((s = br.readLine()) != null) {// 使用readLine方法,一次读一行
				result.add(s);
			}
			br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 执行搜索并复制
	 * @param srcFolderPath 搜索目录
	 * @param destFolderPath 复制目标目录
	 * @param keyword 关键字
	 */
	public static void run(String srcFolderPath, String destFolderPath,
			String keyword,String type) {
		File srcFolder = new File(srcFolderPath);// 默认目录
		File destFolder = new File(destFolderPath);// 目标目录
		if (!srcFolder.exists()) {// 如果文件夹不存在
			System.out.println("目录不存在:" + srcFolder.getAbsolutePath());
			return;
		}
		if (!destFolder.exists()) {// 如果文件夹不存在
			mkDir(destFolder);
			System.out.println("目录创建成功:" + destFolder.getAbsolutePath());
		}
		File[] result = searchFile(srcFolder, keyword);// 调用方法获得文件数组
		System.out.println("在 " + srcFolder + " 以及所有子文件时查找对象" + keyword);
		System.out.println("查找了" + countFiles + " 个文件," + countFolders
				+ " 个文件夹,共找到 " + result.length + " 个符合条件的文件:");
		System.out.println("开始复制以上所有查找到的对象");
		for (int i = 0; i < result.length; i++) {// 循环显示文件
			File file = result[i];
			File destFile = new File(file.getAbsolutePath().replaceFirst(srcFolderPath, destFolderPath));
			if(type!=null&&"move".equals(type)){
				//移动
				file.renameTo(destFile);
			}else{
				//复制
				fileChannelCopy(file, destFile);
			}
			System.out.println(file.getAbsolutePath() + " 复制到 "
					+ destFile.getAbsolutePath());// 显示文件绝对路径
		}
	}

	/**
	 * 创建文件夹
	 * 
	 * @param file
	 */
	public static void mkDir(File file) {
		if (file.getParentFile().exists()) {
			if (!file.exists()) {
				file.mkdir();
			}
		} else {
			mkDir(file.getParentFile());
			file.mkdir();
		}
	}

	/**
	 * 使用文件通道的方式复制文件
	 * 
	 * @param s
	 *            源文件
	 * @param t
	 *            复制到的新文件
	 */
	public static void fileChannelCopy(File s, File t) {
		mkDir(t.getParentFile());
		FileInputStream fi = null;
		FileOutputStream fo = null;
		FileChannel in = null;
		FileChannel out = null;
		try {
			fi = new FileInputStream(s);
			fo = new FileOutputStream(t);
			in = fi.getChannel();// 得到对应的文件通道
			out = fo.getChannel();// 得到对应的文件通道
			in.transferTo(0, in.size(), out);// 连接两个通道,并且从in通道读取,然后写入out通道
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fi.close();
				in.close();
				fo.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 递归查找包含关键字的文件
	 * 
	 * @param folder
	 * @param keyWord
	 * @return
	 */
	public static File[] searchFile(File folder, final String keyWord) {
		File[] subFolders = folder.listFiles(new FileFilter() {// 运用内部匿名类获得文件
					public boolean accept(File pathname) {// 实现FileFilter类的accept方法
						if (pathname.isFile())// 如果是文件
							countFiles++;
						else
							// 如果是目录
							countFolders++;
						if (pathname.isDirectory()
								|| (pathname.isFile() && pathname.getName()
										.toLowerCase()
										.contains(keyWord.toLowerCase())))// 目录或文件包含关键字
							return true;
						return false;
					}
				});

		List result = new ArrayList();// 声明一个集合
		if (subFolders != null) {
			for (File subFolder : subFolders) {// 循环显示文件夹或文件
				if (subFolder.isFile()) {// 如果是文件则将文件添加到结果列表中
					result.add(subFolder);
				} else {// 如果是文件夹,则递归调用本方法,然后把所有的文件加到结果列表中
					File[] foldResult = searchFile(subFolder, keyWord);
					if (foldResult != null) {
						for (File fold : foldResult) {// 循环显示文件
							result.add(fold);// 文件保存到集合中
						}
					}
				}
			}
		}

		File files[] = new File[result.size()];// 声明文件数组,长度为集合的长度
		result.toArray(files);// 集合数组化
		return files;
	}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Scanner;

public class TextCopyUtil {
	static int countFiles = 0;// 声明统计文件个数的变量
	static int countFolders = 0;// 声明统计文件夹的变量

	static String srcFolderPath = "D:\\\\快盘";// 默认目录
	static String destFolderPath = "D:\\\\1360Downloads";// 目标目录
	static String keyword = "会议纪要.txt";
	static String type = "copy";
	
	public static void main(String[] args) {// java程序的主入口处
		System.out.println("现在开始操作批量处理文件");
		System.out.println("你要处理的文件为:"+args[0]);
		List<String> result = txt2StringList(new File(args[0]));
		
		System.out.print("\t默认目录");
		System.out.print("\t目标目录");
		System.out.print("\t关键字");
		System.out.println("\t处理方式(move表示移动,copy表示复制)");
		
		for (String string : result) {
			String[] arr = string.split("\t");
			String srcFolderPath = arr[0];// 默认目录
			String destFolderPath = arr[1];// 目标目录
			String keyword = arr[2];
			String type = arr[3];
			
			System.out.print("\t"+srcFolderPath);
			System.out.print("\t"+destFolderPath);
			System.out.print("\t"+keyword);
			System.out.println("\t"+type);
			
			Scanner input = new Scanner(System.in);
			System.out.println("如果和预期一致请输入数字1,否则其他数字");
				String name = input.nextLine();
				if("1".equals(name)){
					System.out.println(Calendar.getInstance().getTimeInMillis());
					run(srcFolderPath, destFolderPath, keyword, type);
					System.out.println(Calendar.getInstance().getTimeInMillis());
				}
			}
		}
	
	public static List<String> txt2StringList(File file) {
		List<String> result = new ArrayList<String>();
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));// 构造一个BufferedReader类来读取文件
			String s = null;
			while ((s = br.readLine()) != null) {// 使用readLine方法,一次读一行
				result.add(s);
			}
			br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 执行搜索并复制
	 * @param srcFolderPath 搜索目录
	 * @param destFolderPath 复制目标目录
	 * @param keyword 关键字
	 */
	public static void run(String srcFolderPath, String destFolderPath,
			String keyword,String type) {
		File srcFolder = new File(srcFolderPath);// 默认目录
		File destFolder = new File(destFolderPath);// 目标目录
		if (!srcFolder.exists()) {// 如果文件夹不存在
			System.out.println("目录不存在:" + srcFolder.getAbsolutePath());
			return;
		}
		if (!destFolder.exists()) {// 如果文件夹不存在
			mkDir(destFolder);
			System.out.println("目录创建成功:" + destFolder.getAbsolutePath());
		}
		File[] result = searchFile(srcFolder, keyword);// 调用方法获得文件数组
		System.out.println("在 " + srcFolder + " 以及所有子文件时查找对象" + keyword);
		System.out.println("查找了" + countFiles + " 个文件," + countFolders
				+ " 个文件夹,共找到 " + result.length + " 个符合条件的文件:");
		System.out.println("开始复制以上所有查找到的对象");
		for (int i = 0; i < result.length; i++) {// 循环显示文件
			File file = result[i];
			File destFile = new File(file.getAbsolutePath().replaceFirst(srcFolderPath, destFolderPath));
			if(type!=null&&"move".equals(type)){
				//移动
				file.renameTo(destFile);
			}else{
				//复制
				fileChannelCopy(file, destFile);
			}
			System.out.println(file.getAbsolutePath() + " 复制到 "
					+ destFile.getAbsolutePath());// 显示文件绝对路径
		}
	}

	/**
	 * 创建文件夹
	 * 
	 * @param file
	 */
	public static void mkDir(File file) {
		if (file.getParentFile().exists()) {
			if (!file.exists()) {
				file.mkdir();
			}
		} else {
			mkDir(file.getParentFile());
			file.mkdir();
		}
	}

	/**
	 * 使用文件通道的方式复制文件
	 * 
	 * @param s
	 *            源文件
	 * @param t
	 *            复制到的新文件
	 */
	public static void fileChannelCopy(File s, File t) {
		mkDir(t.getParentFile());
		FileInputStream fi = null;
		FileOutputStream fo = null;
		FileChannel in = null;
		FileChannel out = null;
		try {
			fi = new FileInputStream(s);
			fo = new FileOutputStream(t);
			in = fi.getChannel();// 得到对应的文件通道
			out = fo.getChannel();// 得到对应的文件通道
			in.transferTo(0, in.size(), out);// 连接两个通道,并且从in通道读取,然后写入out通道
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fi.close();
				in.close();
				fo.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 递归查找包含关键字的文件
	 * 
	 * @param folder
	 * @param keyWord
	 * @return
	 */
	public static File[] searchFile(File folder, final String keyWord) {
		File[] subFolders = folder.listFiles(new FileFilter() {// 运用内部匿名类获得文件
					public boolean accept(File pathname) {// 实现FileFilter类的accept方法
						if (pathname.isFile())// 如果是文件
							countFiles++;
						else
							// 如果是目录
							countFolders++;
						if (pathname.isDirectory()
								|| (pathname.isFile() && pathname.getName()
										.toLowerCase()
										.contains(keyWord.toLowerCase())))// 目录或文件包含关键字
							return true;
						return false;
					}
				});

		List result = new ArrayList();// 声明一个集合
		if (subFolders != null) {
			for (File subFolder : subFolders) {// 循环显示文件夹或文件
				if (subFolder.isFile()) {// 如果是文件则将文件添加到结果列表中
					result.add(subFolder);
				} else {// 如果是文件夹,则递归调用本方法,然后把所有的文件加到结果列表中
					File[] foldResult = searchFile(subFolder, keyWord);
					if (foldResult != null) {
						for (File fold : foldResult) {// 循环显示文件
							result.add(fold);// 文件保存到集合中
						}
					}
				}
			}
		}

		File files[] = new File[result.size()];// 声明文件数组,长度为集合的长度
		result.toArray(files);// 集合数组化
		return files;
	}
}

效果如下:

附读取规则文件内容

D:\快盘\[MobileBackup]	D:\\1360Downloads	.mp3	copy
D:\快盘\[MobileBackup]\[Pictures]\Pictures	D:\\1360Downloads	.png	copy
D:\快盘\[MobileBackup]	D:\\1360Downloads	.mp3	copy
D:\快盘\[MobileBackup]\[Pictures]\Pictures	D:\\1360Downloads	.png	copy