1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
| import java.security.MessageDigest import java.util.stream.Collectors
class SimilarCalculate { static void main(String[] args) { if (args == null || args.length < 2) { return } String path1 = args[0] String path2 = args[1] compareByCode(path1, path2) println("--------------------------------------") compareByShell(path1, path2) }
private static void compareByCode(String path1, String path2) { def f1 = new File(path1) def f2 = new File(path2) int diffCount1, nonCount1, diffCount2, nonCount2 (diffCount1, nonCount1) = compareDir(f1, f2) (diffCount2, nonCount2) = compareDir(f2, f1) println("Value: $diffCount1, $nonCount1, $diffCount2, $nonCount2") printResult(f1, diffCount1 + nonCount1 + nonCount2) }
private static List<Integer> compareDir(File src, File des) { if (!src.isDirectory() || !des.isDirectory()) { return } int diffCount = 0 int nonCount = 0 src.eachFileRecurse { if (it.isFile()) { String subPath = src.relativePath(it) File desFile = new File(des, subPath) if (desFile.exists()) { if (!fileSame(it, desFile)) { diffCount++ } } else { nonCount++ } } } return [diffCount, nonCount] }
private static void printResult(File origin, int diff) { int total = 0 origin.eachFileRecurse { if (it.isFile()) { total++ } } println("Diff: ${diff}, Total: ${total}, Percentage: ${diff * 1f / total}") }
private static void compareByShell(String path1, String path2) { def f1 = new File(path1) def f2 = new File(path2) createDir(f1, f2) createDir(f2, f1) String result = "diff -rq $path1 $path2".execute().text.trim() printResult(f1, getLineNumberByIo(result)) }
private static int getLineNumberByIo(String target) { LineNumberReader lnr = new LineNumberReader(new CharArrayReader(target.toCharArray())) lnr.skip(Long.MAX_VALUE) lnr.close() return lnr.getLineNumber() + 1 }
private static void createDir(File src, File des) { if (!src.isDirectory() || !des.isDirectory()) { return } src.eachFileRecurse { if (it.isDirectory()) { String subPath = src.relativePath(it) File newFile = new File(des, subPath) if (!newFile.exists()) {
newFile.mkdirs() } } } }
private static boolean fileSame(File f1, File f2) { return getMD5(f1) == getMD5(f2)
}
private static String is2String(InputStream is) { return new BufferedReader(new InputStreamReader(is)).lines().parallel().collect(Collectors.joining("\n")); }
private static String getMD5(File file) { FileInputStream fileInputStream = null try { MessageDigest MD5 = MessageDigest.getInstance("MD5") fileInputStream = new FileInputStream(file) byte[] buffer = new byte[8192] int length while ((length = fileInputStream.read(buffer)) != -1) { MD5.update(buffer, 0, length) } return new String(encodeHex(MD5.digest())) } catch (Exception e) { e.printStackTrace() return null } finally { try { if (fileInputStream != null) { fileInputStream.close() } } catch (IOException e) { e.printStackTrace() } } }
private static final char[] DIGITS_LOWER = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
private static final char[] DIGITS_UPPER = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
public static char[] encodeHex(final byte[] data) { return encodeHex(data, true); }
public static char[] encodeHex(final byte[] data, final boolean toLowerCase) { return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER); }
protected static char[] encodeHex(final byte[] data, final char[] toDigits) { final int l = data.length; final char[] out = new char[l << 1]; for (int i = 0, j = 0; i < l; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return out; } }
|