背景:公司测试没权限接触代码,每次新版本有开发打包
在生产中一般会碰到这样一种情况,开发打包之后,部分文件是自己测试使用的,比如配置文件,而生产环境中,配置文件都是固定的,
如果每次要去打开文件检查配置很麻烦,
所以写一个小工具来缩小检查范围,减少检查时间,降低发布风险
工具流程:
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;
}
}