package bs.util.tool.commongui.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.codec.digest.DigestUtils; import bs.util.tool.commongui.GuiUtils; public final class FileUtils { /** * 相同大小文件查找时用的Map. * * <pre> * key的格式:"文件大小". * </pre> */ public static Map<String, List<File>> sameSizeFilesMap; /** * 重复文件查找时用的Map. * * <pre> * key的格式:"文件大小:MD5". */ public static Map<String, List<File>> repeatFilesMap; /** * 重复文件查找时用的Set. * * <pre> * 元素String的格式:"文件大小:MD5". * 判断repeatFilesMap的value List<File>.size()>1,则加入repeatFilesProp中. * </pre> */ public static Set<String> repeatFilesProp; /** * 同名文件查找时用的Map. * * <pre> * key的格式:"文件名". * </pre> */ public static Map<String, List<File>> sameNameFilesMap; /** * 同名文件查找时用的Set. * * <pre> * 元素String的格式:"文件名". * 判断sameNameFilesMap的value List<File>.size()>1,则加入sameNameFilesProp中. * </pre> */ public static Set<String> sameNameFilesProp; /** * 迭代获取文件夹目录下所有文件(夹). * * @param path * 文件夹目录地址 * @param paramsMap * 参数 * @return <code>List<File></code> 文(夹)件集合 */ public static List<File> getAllSubFiles(String path, Map<String, Object> paramsMap) { File file = new File(path); List<File> fileList = new ArrayList<File>(); SearchFileAndFolderNamePathParams searchFileAndFolderNamePathParams = new SearchFileAndFolderNamePathParams( paramsMap); if (file.isDirectory()) { loopDirectory(file, fileList, searchFileAndFolderNamePathParams); } // 重复文件查找 计算相同大小文件的MD5值 if (searchFileAndFolderNamePathParams.type_repeatSearch) { for (String fileSize : sameSizeFilesMap.keySet()) { for (File sameSizeFile : sameSizeFilesMap.get(fileSize)) { try { byte[] bytes = new byte[2048]; new FileInputStream(sameSizeFile).read(bytes); String prop = fileSize + ":" + DigestUtils.md5Hex(bytes); List<File> repeatFiles = repeatFilesMap.get(prop); if (repeatFiles == null) { repeatFiles = new ArrayList<File>(); repeatFilesMap.put(prop, repeatFiles); } else if (repeatFiles.size() > 0) { repeatFilesProp.add(prop); } repeatFiles.add(sameSizeFile); } catch (FileNotFoundException e) { GuiUtils.log(e); } catch (IOException e) { GuiUtils.log(e); } } } } else if (searchFileAndFolderNamePathParams.type_sameNameSearch) { // 同名文件查找 for (String fileName : sameNameFilesMap.keySet()) { List<File> sameFiles = sameNameFilesMap.get(fileName); if (sameFiles.size() > 1) { sameNameFilesProp.add(fileName); } } } return fileList; } /** * 迭代目录,将符合条件的文件(不包括文件夹)添加到fileList中. * * @param directory * 目录 * @param fileList * file集合 * @param sps * 参数 */ public static void loopDirectory(File directory, List<File> fileList, SearchFileNameParams sps) { File[] files = directory.listFiles(); if (files == null) { return; } for (File file : files) { if (file.isDirectory()) { loopDirectory(file, fileList, sps); } else { ifAddFile(file, fileList, sps); } } } /** * 迭代目录,将符合条件的子文件或子文件夹添加到fileList中. * * @param directory * 目录 * @param fileList * file集合 * @param sps * 参数 */ private static void loopDirectory(File directory, List<File> fileList, SearchFileAndFolderNamePathParams sps) { File[] files = directory.listFiles(); if (files == null) { return; } for (File file : files) { ifAddFile(file, fileList, sps); if (file.isDirectory()) { loopDirectory(file, fileList, sps); } } } /** * 迭代获取地址所有文件(夹),包括file本身. * * @param file * 文件(夹) * @param paramsMap * 参数 * @return <code>List<File></code> 文(夹)件集合 */ public static List<File> getAllFile(File file) { List<File> fileList = new ArrayList<File>(); if (file.exists()) { fileList.add(file); } if (file.isDirectory()) { loopDirectory(file, fileList); } return fileList; } /** * 迭代目录,将所有子文件或者子文件夹添加到fileList中. * * @param directory * 目录 * @param fileList * file集合 */ public static void loopDirectory(File directory, List<File> fileList) { File[] files = directory.listFiles(); if (files == null) { return; } for (File file : files) { fileList.add(file); if (file.isDirectory()) { loopDirectory(file, fileList); } } } /** * 根据条件判断是否将文件add到file集合. * * @param file * 文件 * @param fileList * file集合 * @param sps * 参数 */ private static void ifAddFile(File file, List<File> fileList, SearchFileNameParams sps) { // 判断文件名是否满足匹配 if (FileUtils.ifMatchText(file.getName(), sps.fileNameCsText, sps.fileNameNCsText, sps.fileNameSRegex, sps.fileNameCsPattern, sps.fileNameNCsPattern)) { fileList.add(file); } } /** * 根据条件判断是否将文件(夹)add到file集合. * * @param file * 文件(夹) * @param fileList * file集合 * @param sps * 参数 */ private static void ifAddFile(File file, List<File> fileList, SearchFileAndFolderNamePathParams sps) { boolean hidden = file.isHidden(); boolean isDir = file.isDirectory(); // 是否是查找空文件/文件夹 if (sps.type_blankSearch && ((isDir && (file.listFiles() == null || file.listFiles().length != 0)) || (!isDir && file.length() != 0))) { return; } boolean ifAdd = ifAddFileFolderHidden(hidden, isDir, sps); // 判断是否包括隐藏文件、非隐藏文件、文件、文件夹 if (ifAdd) { ifAdd = ifInSideTime(file.lastModified(), sps.modifyTimeFrom, sps.modifyTimeTo); // 比较修改时间 } if (ifAdd) { // 文件(夹)路径包含(不包含)字符 ifAdd = ifMatchText(file.getAbsolutePath(), sps.filePathCsText, sps.filePathNCsText, sps.filePathSRegex, sps.filePathCsPattern, sps.filePathNCsPattern); } if (ifAdd) { if (isDir) { if (!sps.type_repeatSearch && !sps.type_sameNameSearch) { // 文件夹路径包含(不包含)字符 ifAdd = ifMatchText(file.getAbsolutePath(), sps.folderPathCsText, sps.folderPathNCsText, sps.folderPathSRegex, sps.folderPathCsPattern, sps.folderPathNCsPattern); } } else { long fileSize = file.length(); ifAdd = ifInSideSize(fileSize, sps.sizeFrom, sps.sizeTo); // 比较文件大小 if (ifAdd) { String fileName = file.getName(); String fileType = getFileType(fileName); ifAdd = sps.fileType.length() == 0 || ("," + sps.fileType + ",").contains("," + fileType + ","); // 比较文件类型 if (ifAdd) { // 文件名包含(不包含)字符 ifAdd = ifMatchText(fileName, sps.fileNameCsText, sps.fileNameNCsText, sps.fileNameSRegex, sps.fileNameCsPattern, sps.fileNameNCsPattern); // 比较名称/路径是否匹配 } if (ifAdd) { if (sps.type_repeatSearch) { // 重复文件查找 先找到大小相同的文件 String prop = Long.toString(fileSize); List<File> sameSizeFiles = sameSizeFilesMap.get(prop); if (sameSizeFiles == null) { sameSizeFiles = new ArrayList<File>(); sameSizeFilesMap.put(prop, sameSizeFiles); } sameSizeFiles.add(file); } else if (sps.type_sameNameSearch) { // 重复文件查找 先找到大小相同的文件 String prop = fileName.substring(0, fileName.length() - fileType.length() - 1); List<File> sameNameFiles = sameNameFilesMap.get(prop); if (sameNameFiles == null) { sameNameFiles = new ArrayList<File>(); sameNameFilesMap.put(prop, sameNameFiles); } sameNameFiles.add(file); } } } } } // 当查找类型为'重复文件查找',files最后长度为0,结果保存在FileUtils.repeatFilesProp及FileUtils.repeatFilesMap中 // 当查找类型为'同名文件查找',files最后长度为0,结果保存在FileUtils.sameNameFilesProp及FileUtils.sameNameFilesMap中 if (ifAdd && !sps.type_repeatSearch && !sps.type_sameNameSearch) { fileList.add(file); } } /** * 判断是否包括隐藏文件、非隐藏文件、文件、文件夹. */ public static boolean ifAddFileFolderHidden(boolean hidden, boolean isDir, SearchFileAndFolderNamePathParams sps) { boolean add = true; if (!isDir && !sps.containsFile) { add = false; } else if (isDir && !sps.containsFolder) { add = false; } if (!hidden && !sps.containsNotHidden) { add = false; } else if (hidden && !sps.containsHidden) { add = false; } return add; } /** * 比较是否在时间之间. */ public static boolean ifInSideTime(long side, Long from, Long to) { boolean inSide = true; if (from != null && to == null) { inSide = side >= from; } else if (from == null && to != null) { inSide = side <= to; } else if (from != null && to != null) { inSide = side >= from && side <= to; } return inSide; } /** * 比较是否在大小之间. */ public static boolean ifInSideSize(long side, Double from, Double to) { boolean inSide = true; if (from != null && to == null) { inSide = side >= from; } else if (from == null && to != null) { inSide = side <= to; } else if (from != null && to != null) { inSide = side >= from && side <= to; } return inSide; } /** * 获取文件后缀名,小写. */ public static String getFileType(String fileName) { String fileType = ""; int lIndex = fileName.lastIndexOf("."); if (lIndex > 0) { fileType = fileName.substring(lIndex + 1, fileName.length()).toLowerCase(); } return fileType; } /** * 判断文件(夹)名是否满足匹配. */ public static boolean ifMatchText(String fileName, String csText, String ncsText, boolean sRegex, Pattern csPattern, Pattern ncsPattern) { boolean match = true; String lFileName = fileName.toLowerCase(); String lcsText = csText.toLowerCase(); String lncsText = ncsText.toLowerCase(); if (sRegex) { if (csText.length() != 0) { Matcher m = csPattern.matcher(fileName); match = m.find(); } if (match && ncsText.length() != 0) { Matcher m = ncsPattern.matcher(fileName); match = !m.find(); } } else { if (csText.length() != 0) { match = lFileName.contains(lcsText); } if (match && ncsText.length() != 0) { match = !lFileName.contains(lncsText); } } return match; } }