[Java]比较两个目录的异同(隐藏子目录以改目录下的文件忽略比较)
2011-03-19 00:47 花晓霜 阅读(2360) 评论(0) 编辑 收藏 举报主要想比较文件的大小和最后的更新时间,如果两者都一样则认为一样。否则认为不相同。
首先定了一个文件类FileEntity.java来存储一些文件所必要的属性。
/** * * @author Phonnie * */ public class FileEntity { private String name; private String path; private Date lastModified; private String size; private boolean isHidden; private boolean isFile; private boolean isDirectory; /** * 代表目录或者文件所在的层级,其实目录为0 */ private int level; public FileEntity() { } public FileEntity(String name, String path, Date lastModified, String size, boolean isHidden, boolean isFile,boolean isDirectory) { this.name = name; this.isDirectory = isDirectory; this.isFile = isFile; this.isHidden = isHidden; this.lastModified = lastModified; this.path = path; this.size = size; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public Date getLastModified() { return lastModified; } public void setLastModified(Date lastModified) { this.lastModified = lastModified; } public String getSize() { return size; } public void setSize(String size) { this.size = size; } public boolean isHidden() { return isHidden; } public void setHidden(boolean isHidden) { this.isHidden = isHidden; } public boolean isFile() { return isFile; } public void setFile(boolean isFile) { this.isFile = isFile; } public boolean isDirectory() { return isDirectory; } public void setDirectory(boolean isDirectory) { this.isDirectory = isDirectory; } public void setLevel(int level) { this.level = level; } public int getLevel() { return level; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Name:" + name + ",\n"); sb.append("Path:" + path + ",\n"); sb.append("IsFile:" + isFile + ",\n"); sb.append("Hidden:" + isHidden + ",\n"); sb.append("IsDirectory:" + isDirectory + ",\n"); sb.append("Size:" + size + ",\n"); sb.append("Level:"+level+"\n"); sb.append("LastModified:"+ DateHelper.format(lastModified, "yyyy-MM-dd HH:mm:ss\n")); return sb.toString(); } public boolean equals(FileEntity o) { if ( o == null ) { return false; } else { if(this.isDirectory() && o.isDirectory()) { return o.getLastModified().getTime() == this.getLastModified().getTime(); } else if(this.isFile() && o.isFile()) { return this.getSize().equals(o.getSize()) && this.getLastModified().getTime() == o.getLastModified().getTime(); } return false; } } }
然后顶一个文件操作类来操作文件
/** * * @author Phonnie * */ public class FileHelper { private static Logger _logger = Logger.getLogger(FileHelper.class.getName()); public static String getFileSize(File file){ if(file.isDirectory()) { return null; } try { FileInputStream fis = new FileInputStream(file); int size = fis.available(); return String.format("%,d B", size); } catch (FileNotFoundException e) { e.printStackTrace(); _logger.info("File not found:"+file.getName()); } catch (IOException e) { e.printStackTrace(); _logger.info("IO Exception:" + e.getMessage()); } return null; } public static void traversingDir(File file,List<FileEntity> list) { String name = file.getName(); String path = file.getPath(); String size = getFileSize(file); Date lastModified = new Date(file.lastModified()); if (file.isFile()) { FileEntity o = new FileEntity(name, path, lastModified, size, file.isHidden(), true, false); list.add(o); } else { FileEntity o = new FileEntity(name, path, lastModified, size, file.isHidden(), false, true); list.add(o); File[] files = file.listFiles(); for (File f : files) { traversingDir(f, list); } } } public static void output(List<FileEntity> list) { for (FileEntity fileEntity : list) { System.out.println(fileEntity.toString()); } } public static Map<Integer,List<FileEntity>> doCompare(List<FileEntity> srcList, List<FileEntity> destList, String src, String dest) { Map<Integer,List<FileEntity>> map = new HashMap<Integer,List<FileEntity>>(); removeHiddens(srcList); removeHiddens(destList); for (FileEntity o : srcList) { if(o.getLevel()!=0) { if(map.containsKey(o.getLevel())) { map.get(o.getLevel()).add(o); }else { List<FileEntity> list = new ArrayList<FileEntity>(); list.add(o); map.put(o.getLevel(), list); } } } for (FileEntity o : destList) { if(o.getLevel() != 0) { if(map.containsKey(o.getLevel())) { FileEntity entity = getFileEntity(map.get(o.getLevel()),o); if(entity == null) { map.get(o.getLevel()).add(o); } else { doRemove(map.get(o.getLevel()),entity); } }else { List<FileEntity> list = new ArrayList<FileEntity>(); list.add(o); map.put(o.getLevel(), list); } } } return map; } private static void doRemove(List<FileEntity> list,FileEntity o) { FileEntity result = null; for (FileEntity entity : list) { if(o.equals(entity)) { result = entity; break; } } list.remove(result); } public static void removeHiddens(List<FileEntity> list) { List<FileEntity> hiddens = new ArrayList<FileEntity>(); for (FileEntity o : list) { if(o.isHidden()) { hiddens.add(o); } } List<FileEntity> result = new ArrayList<FileEntity>(); for (FileEntity o : hiddens) { for (FileEntity entity : list) { if(entity.getPath().indexOf(o.getName())>-1) { result.add(entity); } } } list.removeAll(result); } private static FileEntity getFileEntity(List<FileEntity> list,FileEntity o) { for (FileEntity entity : list) { if((o.isFile() && entity.isFile() || o.isDirectory() && entity.isDirectory())) { if(o.getName().equals(entity.getName())) { return entity; } } } return null; } public static void setLevels(List<FileEntity> list,String src) { for (FileEntity o : list) { setLevel(o, src); } } private static void setLevel(FileEntity o,String src) { if(src.equals(o.getPath())) { o.setLevel(0); }else { src = src.replace(File.separator, "/"); String path = o.getPath().replace(File.separator, "/"); int srcLength = src.split("/").length; int length =path.split("/").length; length -=srcLength; o.setLevel(length); } } }
接下里是两个文件目录比较
/** * * @author Phonnie * */ public class DirectoryComparison { public static void compare(String src,String dest) { File srcFile = new File(src); File destFile = new File(dest); List<FileEntity> srcList = new ArrayList<FileEntity>(); List<FileEntity> destList = new ArrayList<FileEntity>(); Map<Integer,List<FileEntity>> map = null; if(!srcFile.exists() || !destFile.exists()) { return; } FileHelper.traversingDir(srcFile, srcList); FileHelper.traversingDir(destFile, destList); FileHelper.setLevels(srcList, src); FileHelper.setLevels(destList, dest); FileHelper.output(srcList); FileHelper.output(destList); map = FileHelper.doCompare(srcList, destList, src, dest); System.out.println("----------------Result:-----------------"); for (Entry<Integer,List<FileEntity>> entry : map.entrySet()) { System.out.println("######## Level:" + entry.getKey() +" ###################\n"); FileHelper.output(entry.getValue()); System.out.println("#######################################"); } } }
接下来写个测试入口程序打成可以执行的jar包,写个批处理就可以直接执行了
public class Demo { /** * @param args */ public static void main(String[] args) { if(args==null) { Logger.getLogger(Demo.class.getName()).info("Arguments error!!!"); return; } if(args.length!=2) { for (int i = 0; i < args.length; i++) { System.out.println("arg"+i+":"+args[i]); } Logger.getLogger(Demo.class.getName()).info("args has been too many!!!"); return; } try { DirectoryComparison.compare(args[0], args[1]); } catch (Exception e) { e.printStackTrace(); } } }
附加一个DateHelper.java
/** * 类名:日期辅助类 * * @author Phonnie * */ public class DateHelper { /** * 日志 * */ private static Logger _logger = Logger.getLogger(DateHelper.class.getName()); /** * 将指定格式的字符串转化成日期 * * @param day * 日期字符串 * @param format * 格式化字符串 * @return 日期 */ public static Date getDate(String date, String format) { Date d = null; SimpleDateFormat df = new SimpleDateFormat(format); try { d = df.parse(date); } catch (Exception e) { _logger.info("Parse string " + date + " to Date failed :" + e.getMessage()); return null; } return d; } /** * 将日期转换成指定格式的字符串 * * @param date * 日期 * @param format * 格式化字符串 * @return 格式化后的日子字符串 */ public static String format(Date date, String format) { String d = null; SimpleDateFormat df = new SimpleDateFormat(format); try { d = df.format(date); } catch (Exception e) { _logger.info("Parse Date " + date + " to String failed :" + e.getMessage()); return null; } return d; } }
批处理如下:
1 @echo off
2
3 SETLOCAL ENABLEDELAYEDEXPANSION
4
5 if "%1"=="" (
6 set /p arg1=输入起始路径:
7 ) else set arg1=%1
8
9 if "%2"=="" (
10 set /p arg2=输入目标路径:
11 ) else set arg2=%2
12
13
14
15 echo 开始执行...
16
17 java -jar ./bin/dir-util.jar "%arg1%" "%arg2%"
18
19 pause
搞定试试^_^