代码改变世界

[Java]比较两个目录的异同(隐藏子目录以改目录下的文件忽略比较)

2011-03-19 00:47  花晓霜  阅读(2355)  评论(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

搞定试试^_^