-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.cpp
101 lines (88 loc) · 3.02 KB
/
app.cpp
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
/*
made by: Michael Scholten
created: 10th of July 2020
updated: 20th of February 2022
*/
#include <iostream>
#include <dirent.h>
#include <vector>
#include <fstream>
#include <sstream>
void getDirectoryEntries(const std::string&, std::vector<std::string>&);
std::string readFile(const std::string&);
void filterDirectory(const std::string&);
int main() {
while(true){
// request a directory from the user
std::string path;
std::cout << "Enter the directory to remove duplicate files from: ";
std::cin >> path;
// make sure the path ends with a '/'
if(path[path.size() - 1] != '/'){
path += "/";
}
// filter the directory
filterDirectory(path);
}
}
void getDirectoryEntries(const std::string& directoryPath, std::vector<std::string>& entries){
// declare a directory entry pointer
struct dirent *entry;
// open the directory, so we can read it's entries
DIR *directory = opendir(directoryPath.c_str());
// only if the directory exists, we can search for entries
if(directory != NULL){
// iterate through the directory entries
while((entry = readdir(directory)) != NULL){
// only add an entry if it isn't a directory
if(entry->d_type != DT_DIR){
// add the entry to the end of the vector
entries.push_back(directoryPath + entry->d_name);
}
}
// close the directory as we are done using it
closedir(directory);
}
}
std::string readFile(const std::string& fileName){
// read the file in binary, so the program works for all files
std::ifstream file(fileName, std::ios::binary);
// only if the file did open, we read the content
if(file.is_open()){
// read the content of the file and return it
std::stringstream content;
content << file.rdbuf();
return content.str();
}else{
// if we were unable to open the file, we display and error message and return and empty string
std::cerr << "ERROR: Failed to open file [" << fileName << "]!\n";
return "";
}
}
void filterDirectory(const std::string& path){
// create a new vector for the entries and add all the entries in the given directory to the vector
std::vector<std::string> entries;
getDirectoryEntries(path, entries);
// store the resulting size, so we can calculate the number of removed entries
size_t originalSize = entries.size();
// iterate through the entries
for(size_t i = 0;i < entries.size();i++){
// start the inner iterator 1 position farther than the current position of the outer iterator
size_t j = i + 1;
while(j < entries.size()){
// check whether the contents of the entries are the same
std::string checkDirectory = entries[j];
if(readFile(entries[i]) == readFile(checkDirectory)){
// if so, we delete the file and remove it from the vector
remove(checkDirectory.c_str());
entries.erase(entries.begin() + j);
std::cout << "Removed: " << checkDirectory << "\n";
}else{
// if the contents were not equal, we increment the outer iterator
j++;
}
}
}
// display the amount of files that were removed
std::cout << "Removed " << originalSize - entries.size() << " files.\n";
}