-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDeduplicator.java
More file actions
105 lines (95 loc) · 4.41 KB
/
Deduplicator.java
File metadata and controls
105 lines (95 loc) · 4.41 KB
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
import com.sun.istack.internal.NotNull;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Stream;
class MyComparator implements Comparator<List<Path>> {
@Override
public int compare(List<Path> listOfPath1, List<Path> listOfPath2) {
long comp = -1;
try {
if (listOfPath1.isEmpty() || listOfPath2.isEmpty())
throw new RuntimeException();
comp = Deduplicator.compare(listOfPath1.get(0), listOfPath2.get(0));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return (comp > 0) ? 1 :
(comp < 0) ? -1 :
0;
}
};
public class Deduplicator {
public static long compare(Path file1, Path file2) throws IOException {
//better throw exception ?
if (Files.isDirectory(file1) || Files.isDirectory(file2))
return 0;
long diff = Files.size(file1) - Files.size(file2);
if (diff != 0)
return diff;
//otherwise
int byte1, byte2;
try (
BufferedInputStream f1 = new BufferedInputStream(Files.newInputStream(file1));
BufferedInputStream f2 = new BufferedInputStream(Files.newInputStream(file2));
) {
if (Files.isReadable(file1) && Files.isReadable(file2)) {
//Size files are same
//read byte from file1
while ((byte1 = f1.read()) != -1){
byte2 = f2.read();//then read byte from file2
diff = byte1 - byte2;
if (diff != 0)
return diff;
}
} else
throw new IOException();//???????
}
return 0;
}
public static List<Path> getListFilesCurrentDirectory(Path dir) throws IOException {
Stream<Path> pathStream = Files.walk(dir);
List<Path> list = new LinkedList<>();
//добавляем только файлы, игнорируя папки
pathStream.forEach((f1) -> {
if (!Files.isDirectory(f1)) list.add(f1);
});
return list;
}
//this function build tree
private static Set<List<Path>> buildMyTreeSet(Path path) throws IOException {
TreeSet<List<Path>> setOfPaths = new TreeSet<>(new MyComparator());
List<Path> listAllPath = getListFilesCurrentDirectory(path);
//временный список в котором всегда будем содержаться только один элемент
List<Path> temp = new LinkedList<>(), tempAB = new LinkedList<>();
List<Path> classEquals;
for (Path currentPath : listAllPath) {
temp.add(currentPath);
classEquals = setOfPaths.ceiling(temp);
//если похожих элементов нет - то создаем новый класс эквивалентности
if (null == classEquals || compare(classEquals.get(0), currentPath) != 0) {
//создаем новый класс эквивалентности, состящий из одного элемента
List<Path> addedClassEquals = new LinkedList<>();
addedClassEquals.add(currentPath);
//и добавляем его во множество классов эквивалентности
setOfPaths.add(addedClassEquals);
} else //иначе - добавляем path в соответствующий класс эквивалентности
classEquals.add(currentPath);
//продолжаем поддерживать наличие только одного элемента во временном листе
temp.remove(currentPath);
}
return setOfPaths;
}
public static void writeDublicates(Path path) throws IOException {
Set<List<Path>> setOfPaths = buildMyTreeSet(path);
for (List<Path> listPath : setOfPaths) {
//если есть дубликаты
if (listPath.size() > 1) {
for (Path dublPath : listPath)
System.out.print(dublPath.getFileName() + " ");
System.out.println("are duplicates");
}
}
}
}