背景:公司测试没权限接触代码,每次新版本有开发打包

在生产中一般会碰到这样一种情况,开发打包之后,部分文件是自己测试使用的,比如配置文件,而生产环境中,配置文件都是固定的,

如果每次要去打开文件检查配置很麻烦,

所以写一个小工具来缩小检查范围,减少检查时间,降低发布风险


工具流程:

1、输入路径1

2、输入路径2

3、输入保存路径

4、程序会去获取路径1下的全部文件路径(不包括文件夹)

5、依次计算出每个文件的MD5值,然后记录在map1中,key为路径,V为计算出的MD5值

6、获取路径2下文件的全部路径(不包括文件夹)

7、依次计算出每个文件的MD5值,然后记录在map2中,key为路径,V为计算出的MD5值

8、把map1的key作为查询条件,到map2中去查询对应的MD5值再与map1中的值比较,

9、把结果记录在一个新的map中,key为路径,v为结果,结果有两种,false:表示路径2中有路径1的文件,但是MD5不同,null:表示路径2中没有这个文件

10、把结果map打印到保存路径,生成txt文件


开发工具过程中碰到的问题

1、最开始new的map,key的类型是StringBuffer,但是去map2中查的时候竟然查不到,后来把StringBuffer修改为String后,可以正常运行, 可能是StringBuffer的一些问题吧

(第二天补充,昨天晚上回去查了一下,虽然StringBuffer和String都是引用类型,但是String创建时会检查静态存储区中是否有同样的数据,如果有就直接引用,所以内存地址是一样的,StringBuffer就不同,StringBuffer创建的是一个新的对象,所以内存地址不同,而且map的key存的实际上就是一个内存地址)

2、for循环一个低级的错误,一个表达式的结果返回的一个map,然后直接把表达式填进foreach中,导致程序会产生不可预期的错误,因为运行for循环时会去计算表达式的值,这种写法会导致不可预估的问题。

3、在linux环境运行时,报出too many open files异常,使用ulmit -a查看 open file只有1024,然后编辑/etc/security/limits.conf  在最后加上

* soft nofile 32768
* hard nofile 65536

然后退出ssh重新连接,一定要exit退出,直接关闭ssh窗口一样不生效


运行方式 java -jar CompareFile.jar

源码CompareFile.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.Stack;

public class CompareFile {
		//file1用来放文件的绝对路径
		LinkedList<StringBuffer> file1 =  new  LinkedList<StringBuffer>();
		//file2用来放文件相对路径
//		static LinkedList<StringBuffer> file2 =  new  LinkedList<StringBuffer>();
		static String savepath;
		FindFile findFile = new FindFile();
		static Map<String, String> reMap= new  HashMap<String, String>();
		
	
	private Map<String, String> getMap(StringBuffer path1) {
		/*
		 * 获取文件路径,给map赋值,key是文件相对路径,v是文件MD5
		 * 
		 */
		Map<String, String> map=   new  HashMap<String, String>();
		file1=findFile.getFindFile(path1);
//		file2=findFile.getFindFile(path2);
		//截取多余的目录名
		IsOS os = new IsOS();
		StringBuffer stringBuffer = null; 
		int stlength = 0 ;
		if (os.isOS().equals("linux")) {
			stringBuffer =new StringBuffer(path1.substring(0, path1.lastIndexOf("/")));
			stlength = stringBuffer.length();
		}else if (os.isOS().equals("win")) {
			stringBuffer =new StringBuffer(path1.substring(0, path1.lastIndexOf("\\"))); 
			stlength = stringBuffer.length();
		}else {
			  return null;
		}
		
		
//			System.out.println(stlength);
		int i = 0;
		for (StringBuffer stringBuffer1 : file1) {
			/*
			 * 获取文件相对根目录
			 *data-file-name,则获取neme目录下所有的文件名,不加上data-file
			 */
			StringBuffer stringBuffer2 = new StringBuffer();
			stringBuffer2 = new StringBuffer(stringBuffer1.substring(stlength+1, stringBuffer1.length()));
			map.put(stringBuffer2.toString(), getMD5(new File(stringBuffer1.toString())));

		}
		return map;
		
	}
	
	public String getMD5(File file) {
		/*
		 * 输入一个文件类,返回文件的MD5
		 */
		BigInteger bigInteger = null;
		try {
			
			MessageDigest messageDigest = MessageDigest.getInstance("MD5");
			FileInputStream fin = new FileInputStream(file);
			byte[] buffer = new byte[1024];
			int fr;
			while((fr=fin.read(buffer))!=-1) {
				messageDigest.update(buffer,0,fr);
			}
			bigInteger = new BigInteger(1, messageDigest.digest());
			
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
//		System.out.println("DM5:"+bigInteger.toString(16));
		return bigInteger.toString(16);
	}
	
	
	
	private void compareing() {
		// TODO 自动生成的方法存根
		Scanner sc1 = new Scanner(System.in);
		System.out.println("请输入路径1:");
		StringBuffer path1 = new StringBuffer(sc1.nextLine());
		Scanner sc2 = new Scanner(System.in);
		System.out.println("请输入路径2:");
		StringBuffer path2 = new StringBuffer(sc1.nextLine());
		Scanner sc3 = new Scanner(System.in);
		System.out.println("请输入保存的路径:");
		savepath=new String(sc3.nextLine());
		
		CompareFile compareFile = new CompareFile();
		CompareFile compareFile1 = new CompareFile();
		Map<String, String> map1 = compareFile.getMap(path1);
		Map<String, String> map2 = compareFile1.getMap(path2);
		if (map1!=null&&map2!=null) {
		
		for (String key : map1.keySet()) {
			/*
			 * 比较path1和path2的MD5值
			 */
			if (map2.get(key)==null) {
				System.out.println("路径2中不存在路径1中的:"+key);
				reMap.put(key, "null");
			}else if (map2.get(key).equals(map1.get(key))) {
				reMap.put(key, " ");
			} else {
				reMap.put(key, "false");
			}
			
		}
	}
	}

	public static void main(String[] args) {
//		// TODO 自动生成的方法存根
		CompareFile compareFile = new CompareFile();
		compareFile.compareing();
		WriteFile writeFile = new WriteFile();
		writeFile.writeFlie(savepath, reMap);
		System.out.println("complete!");
	}

}

FindFile.java

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedList;

import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;

import test.TestInterfaceImpl1;

public class FindFile {
	/*
	 * 输入文件夹位置,获取该文件夹下面所有文件的路径
	 */
	
	LinkedList<StringBuffer> filename = new LinkedList<StringBuffer>();
	static LinkedList<StringBuffer> dname = new LinkedList<StringBuffer>();
	

	public LinkedList<StringBuffer> getFindFile(StringBuffer s) {
//		System.out.println(s.toString());
		this.getfilename(new File(s.toString()));
		this.whilename();
		return filename;
		
	}
	

	private void getfilename(File file){
		if (file.listFiles()!=null&&file.listFiles().length!=0) {
			File[] files = file.listFiles();//获取目录列表

			for (File file2 : files) {
				/*
				 * 判断这个是文件还是目录
				 * 文件放到filename,目录放到dname
				 */
				if(file2.isFile()) {
					StringBuffer s1 = new StringBuffer(file2.toString());
					filename.add(s1);
//					System.out.println("1");
				}else if (file.isDirectory()) {
					StringBuffer s2 = new StringBuffer(file2.toString());
					dname.add(s2);
//					System.out.println("2");
				}else {
					System.out.println(file2.toString()+":error,not f or d ");
				}
				
			}
		}
		
	

		
	}
	/*
	 * 调用getfilename
	 */
	private void whilename() {
		while(dname.size()!=0){
			for(int i=0;i<dname.size();i++){
			this.getfilename(new File(dname.get(i).toString()));
			dname.remove(i);
			}
		}
	}



WriteFile.java

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;

public class WriteFile {
	
	
	public void writeFlie(String savepath,Map<String, String> reMap) {
		IsOS isOS = new IsOS();
		File f = null;
		if (isOS.isOS().equals("linux")) {
			if (savepath.endsWith("/")) {
			 f = new File(savepath+"CompareFile.txt");
			}else{
			 f = new File(savepath+"/CompareFile.txt");
			}
		}else if (isOS.isOS().equals("win")) {
			if (savepath.endsWith("\\")) {
				 f = new File(savepath+"CompareFile.txt");
			}else{
			     f = new File(savepath+"\\CompareFile.txt");
			}
		}
		
		try {
			f.createNewFile();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} 
		try {
			FileOutputStream fo = new FileOutputStream(f);
			DataOutputStream is = new DataOutputStream(fo);
			IsOS os = new IsOS();
			if (os.isOS().equals("linux")) {
				for (Map.Entry<String,String> map : reMap.entrySet()) {
//					System.out.println();
					if (map.getValue().equals("false")||map.getValue().equals("null")) {
						is.writeBytes(map.getKey()+" : "+map.getValue()+"\n");
					}
				}
			}else if (os.isOS().equals("win")) {
				for (Map.Entry<String,String> map : reMap.entrySet()) {
//					System.out.println();
					if (map.getValue().equals("false")||map.getValue().equals("null")) {
						is.writeBytes(map.getKey()+" : "+map.getValue()+"\r\n");
					}
				}
			}else {
				System.out.println("未知的操作系统");
			}

		} catch (Exception e1) {
			// TODO 自动生成的 catch 块
			e1.printStackTrace();
		}

	}



}

IsOS.java

public class IsOS {

	public String isOS() {
		String osName = null;
		if (System.getProperty("os.name").indexOf("Windows")!=-1) {
//			System.out.println(System.getProperty("os.name"));
			osName = "win";
		}else if (System.getProperty("os.name").indexOf("Linux")!=-1) {
//			System.out.println(System.getProperty("os.name"));
			osName = "linux";
		}else {
			return null;
		}
		return osName;
	}

}