java file compare utility
程序员文章站
2022-05-09 13:32:43
...
As there is requriement about compare code in two branches , so just write a demo.
function contains:
1.get checksum of string
2.get checksum of files
3.compare two folders.
package com.jsajax.utilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
public class ChecksumUtility {
public static final String ALGORITHM_MD5="MD5";
public static final String ALGORITHM_SHA1="SHA-1";
public static final String FOLDER_MAIN="SRC";
public static final String FOLDER_COMP="DEST";
/***
*
* @param input the string
* @param algorithm the algorithm,e.g MD5 or SHA-1
* @return the string for the resulting hash value
*/
public static String stringChecksum(String input , String algorithm) {
try {
// 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 输入的字符串转换成字节数组
byte[] inputByteArray = input.getBytes();
// inputByteArray是输入字符串转换得到的字节数组
messageDigest.update(inputByteArray);
// 转换并返回结果,也是字节数组,包含16个元素
byte[] resultByteArray = messageDigest.digest();
// 字符数组转换成字符串返回
return byteArrayToHex(resultByteArray);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
/***
*
* @param inputFile the file path
* @param algorithm the algorithm e.g MD5 or SHA-1
* @return the string for the resulting hash value
* @throws IOException
*/
public static String fileChecksum(String inputFile , String algorithm) throws IOException {
// 缓冲区大小
int bufferSize = 256 * 1024;
FileInputStream fileInputStream = null;
DigestInputStream digestInputStream = null;
try {
// 拿到一个MD5转换器(同样,这里可以换成SHA1)
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 使用DigestInputStream
fileInputStream = new FileInputStream(inputFile);
digestInputStream = new DigestInputStream(fileInputStream,
messageDigest);
// read的过程中进行MD5处理,直到读完文件
byte[] buffer = new byte[bufferSize];
while (digestInputStream.read(buffer) > 0)
;
// 获取最终的MessageDigest
messageDigest = digestInputStream.getMessageDigest();
// 拿到结果,也是字节数组,包含16个元素
byte[] resultByteArray = messageDigest.digest();
// 同样,把字节数组转换成字符串
return byteArrayToHex(resultByteArray);
} catch (NoSuchAlgorithmException e) {
return null;
} finally {
try {
digestInputStream.close();
} catch (Exception e) {
}
try {
fileInputStream.close();
} catch (Exception e) {
}
}
}
/***
*
* @param byteArray array of byte
* @return string converted from the byteArray e.g bype[0]=60-->0011 1100-->"3C"
*/
// 下面这个函数用于将字节数组换成成16进制的字符串
public static String byteArrayToHex(byte[] byteArray) {
// 首先初始化一个字符数组,用来存放每个16进制字符
char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F' };
// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,
// 也就是2位十六进制字符(2的8次方等于16的2次方))
char[] resultCharArray = new char[byteArray.length * 2];
// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
int index = 0;
for (byte b : byteArray) {
resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b & 0xf];
}
// 字符数组组合成字符串返回
return new String(resultCharArray);
}
/***
*
* @param srcFolder E:\document\java\test\main\XXX
* @param destFolder E:\document\java\test\comp\XXX
* @remark when compare the 2 folders , the structure under XXX should be same.
* @param firstSameFolderName XXX
* @param outputFolder the output folder about the compare result.
* @return the checksum of both folders.
*/
public static void folderCompare(String srcFolder,String destFolder,String firstSameFolderName,String outputFolder){
File srcF = new File(srcFolder);
File destF = new File(destFolder);
Map<String,String> srcChecksumMap= new HashMap<String,String>();
Map<String,String> destChecksumMap= new HashMap<String,String>();
List<String> allFileList = new ArrayList<String>();
List<String> deleteList = new ArrayList<String>();
List<String> copyList = new ArrayList<String>();
if(srcF.exists()&&srcF.canRead() && destF.exists() && destF.canRead()){
getFileChecksum(srcF,srcChecksumMap,firstSameFolderName);
getFileChecksum(destF,destChecksumMap,firstSameFolderName);
gatherAllFiles(srcChecksumMap,destChecksumMap,allFileList);
System.out.println("srcFolder = "+srcFolder);
System.out.println("destFolder = "+destFolder);
if(allFileList.size()>0){
int index = 1;
String srcFileSum;
String descFileSum;
for(String str : allFileList){
srcFileSum = srcChecksumMap.get(str);
descFileSum = destChecksumMap.get(str);
if(StringUtils.isBlank(srcFileSum) && StringUtils.isNotBlank(descFileSum)){
System.out.println("File["+index+"] = "+str+"\t\tTO_DELETE");
deleteList.add(destFolder+"\\"+str);
}else if(StringUtils.isNotBlank(srcFileSum) && StringUtils.isBlank(descFileSum)){
System.out.println("File["+index+"] = "+str+"\t\tTO_COPY");
copyList.add(str);
}else if(StringUtils.isNotBlank(srcFileSum) && StringUtils.isNotBlank(descFileSum) && !srcFileSum.equalsIgnoreCase(descFileSum)){
System.out.println("File["+index+"] = "+str+"\t\tTO_MODIFY");
copyList.add(str);
}else{
System.out.println("File["+index+"] = "+str);
}
System.out.println("Checksum in srcFolder = "+srcFileSum +"\t\t in destFolder = "+descFileSum);
index++;
}
}
}else{
System.out.println("Both folder can not be read.");
}
System.out.println("Delete below files:");
deleteBelowFiles(deleteList);
System.out.println("Copy out below files:");
copyBelowFIles(copyList,srcFolder,outputFolder);
}
public static void copyBelowFIles(List<String> copyList,String from , String to){
if(copyList.size()>0){
File f;
try {
for(String s:copyList){
f = new File(to+File.separator+s);
CopyUtility.copyFile(from+File.separator+s, to+File.separator+s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void deleteBelowFiles(List<String> deleteList){
if(deleteList.size()>0){
for(String s:deleteList){
System.out.println(s);
//TODO...
}
}
}
public static void gatherAllFiles(Map<String,String> srcChecksumMap,Map<String,String> destChecksumMap , List<String> allFileList){
Set<String> srcFileList = srcChecksumMap.keySet();
Set<String> destFileList = destChecksumMap.keySet();
if(srcFileList.size()>0){
for(String s:srcFileList){
if(!allFileList.contains(s)){
allFileList.add(s);
}
}
}
if(destFileList.size()>0){
for(String s:destFileList){
if(!allFileList.contains(s)){
allFileList.add(s);
}
}
}
}
/***
*
* @param file the File entity of file path "E:\document\java\test\main\XXX"
* @param checksumMap the result checksum map
* @param firstSameFolderName it is XXX
*/
public static void getFileChecksum(File file,Map<String,String> checksumMap,String firstSameFolderName){
if(file.isFile()){
String relativePath = file.getAbsolutePath().substring(file.getAbsolutePath().indexOf(firstSameFolderName)+firstSameFolderName.length()+1);
try {
checksumMap.put(relativePath, fileChecksum(file.getAbsolutePath() , ChecksumUtility.ALGORITHM_SHA1));
} catch (IOException e) {
checksumMap.put(relativePath,"encounter exception.");
}
return;
}else{
File[] files = file.listFiles();
if(files !=null && files.length >0){
for(File f : files){
if(!f.getName().startsWith(".")){ // if the directory or file name is started with '.' , ignore it
getFileChecksum(f,checksumMap,firstSameFolderName);
}
}
}else{
return;
}
}
}
public static void main(String[] args) {
ChecksumUtility.folderCompare("E:\\document\\java\\111111testfolder\\main\\123",
"E:\\document\\java\\111111testfolder\\comp\\123", "123", "E:\\document\\java\\111111testfolder\\result");
}
}
package com.jsajax.utilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class CopyUtility {
public static void createDir(String fileToPath){
String folder = fileToPath.substring(0,fileToPath.lastIndexOf(File.separator));
File f = new File(folder);
if(!f.exists()){
System.out.println("Create folder "+folder);
f.mkdirs();
}
}
public static void createFile(String fileToPath) throws IOException{
File f = new File(fileToPath);
if(!f.exists()){
System.out.println("Create file "+fileToPath);
f.createNewFile();
}
}
public static void copyFile(String fileFromPath, String fileToPath){
InputStream in = null;
OutputStream out = null;
try {
createDir(fileToPath);
createFile(fileToPath);
in = new FileInputStream(fileFromPath);
out = new FileOutputStream(fileToPath);
int length = in.available();
int len = (length % 1024 == 0) ? (length / 1024): (length / 1024 + 1);
byte[] temp = new byte[1024];
for (int i = 0; i < len; i++) {
in.read(temp);
out.write(temp);
}
} catch(Exception e){
e.printStackTrace();
} finally {
if (in != null)
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
if (out != null)
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
推荐阅读
-
详谈java中File类getPath()、getAbsolutePath()、getCanonical的区别
-
java.io.FileNotFoundException:/x/x/x/xx.xls:open failed: ENOENT (No such file or directory)
-
Tomcat启动报错:org.apache.catalina.LifecycleException: Failed to start component...java.util.zip.ZipException: error in opening zip file
-
JAVA基础之File类
-
Java的File类
-
在java程序中如何操作文件和目录(File类)
-
java file获取功能,file.toString()可以拿到路径
-
File类 (Java)
-
Java File IO学习笔记
-
pdfbox Could not load font file: C:\WINDOWS\FONTS\mstmc.ttf java.io.EOFException