|
#include <iostream> |
|
#include <algorithm> |
|
#include <vector> |
|
#include <string> |
|
#include <windows.h> |
|
#include <fstream> |
|
#include <cstring> |
|
#include <cassert> |
|
|
|
using namespace std; |
|
|
|
#define BUFFER_SIZE 4096 |
|
|
|
//判断是否为dir |
|
bool is_dir(const char *file_name) |
|
{ |
|
HANDLE hFile; |
|
WIN32_FIND_DATA FileInformation; |
|
hFile = ::FindFirstFile(file_name, &FileInformation); |
|
if (hFile != INVALID_HANDLE_VALUE) |
|
{ |
|
::FindClose(hFile); |
|
if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
|
{ |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
//判断文件是否存在 |
|
bool file_exist(const char *file_path) |
|
{ |
|
HANDLE hFile; |
|
WIN32_FIND_DATA FileInformation; |
|
hFile = ::FindFirstFile(file_path, &FileInformation); |
|
if (hFile != INVALID_HANDLE_VALUE) |
|
{ |
|
::FindClose(hFile); |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
//比较两个文件内容是否相同 |
|
//没有判断文件是否存在 |
|
bool file_compare(const char *src, const char *dest) |
|
{ |
|
//判断内容是否相同 |
|
char src_buf[BUFFER_SIZE]; |
|
char dest_buf[BUFFER_SIZE]; |
|
fstream src_fs, dest_fs; |
|
int len; |
|
src_fs.open(src, ios_base::in); |
|
dest_fs.open(dest, ios_base::in); |
|
|
|
assert(src_fs.is_open()); |
|
assert(dest_fs.is_open()); |
|
while (true) |
|
{ |
|
if (src_fs.eof() && dest_fs.eof()) |
|
{ |
|
src_fs.close(); |
|
dest_fs.close(); |
|
return true; |
|
} |
|
else if (src_fs.eof() || dest_fs.eof()) |
|
{ |
|
break; |
|
} |
|
|
|
src_fs.read(src_buf, BUFFER_SIZE); |
|
dest_fs.read(dest_buf, BUFFER_SIZE); |
|
|
|
if ((len = src_fs.gcount()) != dest_fs.gcount()) |
|
{ |
|
break; |
|
} |
|
if(memcmp(src_buf, dest_buf, len) != 0) break; |
|
} |
|
src_fs.close(); |
|
dest_fs.close(); |
|
return false; |
|
} |
|
|
|
//列出dir目录下的所有文件 |
|
//dir不能以\\结尾 |
|
void list_dir(const char *dir, vector<string> &fs) |
|
{ |
|
string strDir = dir; |
|
string strPattern; |
|
|
|
HANDLE hFile; |
|
WIN32_FIND_DATA FileInformation; |
|
|
|
strPattern = strDir + "\\*.*"; |
|
hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation); |
|
if (hFile != INVALID_HANDLE_VALUE) |
|
{ |
|
do |
|
{ |
|
//去掉..和.目录 |
|
if (FileInformation.cFileName[0] != '.') |
|
{ |
|
fs.push_back(FileInformation.cFileName); |
|
} |
|
} while (::FindNextFile(hFile, &FileInformation) == TRUE); |
|
|
|
::FindClose(hFile); |
|
} |
|
} |
|
|
|
//比较两个文件或两个文件夹是否相同 |
|
//src和dest不能以\\结尾 |
|
bool diff(const char *src, const char *dest) |
|
{ |
|
string src_path = src; |
|
string dest_path = dest; |
|
|
|
//判断是否存在 |
|
if (file_exist(src_path.c_str()) == false) |
|
{ |
|
#ifdef DEBUG |
|
cout << src_path << " no exist" << endl; |
|
#endif |
|
return false; |
|
} |
|
|
|
if (file_exist(dest_path.c_str()) == false) |
|
{ |
|
#ifdef DEBUG |
|
cout << dest_path << " no exist" << endl; |
|
#endif |
|
return false; |
|
} |
|
|
|
bool dir = is_dir(src_path.c_str()); |
|
//是否同为dir或file |
|
if (dir == is_dir(dest_path.c_str())) |
|
{ |
|
//同为dir |
|
if (dir) |
|
{ |
|
#ifdef DEBUG |
|
cout << "dir compare" << endl; |
|
#endif |
|
vector<string> src_files, dest_files; |
|
//找到目录下所有文件,包括文件夹 |
|
list_dir(src_path.c_str(), src_files); |
|
list_dir(dest_path.c_str(), dest_files); |
|
//按照字符串排序 |
|
sort(src_files.begin(), src_files.end()); |
|
sort(dest_files.begin(), dest_files.end()); |
|
|
|
vector<string>::iterator src_it = src_files.begin(); |
|
vector<string>::iterator dest_it = dest_files.begin(); |
|
|
|
for (; src_it != src_files.end() && dest_it != dest_files.end(); src_it++, dest_it++) |
|
{ |
|
//如果文件名不相同或文件内容不同,则返回false |
|
#ifdef DEBUG |
|
cout << *src_it << " " << *dest_it << endl; |
|
#endif |
|
if ((*src_it) != (*dest_it) || diff((src_path + "\\" + src_it->c_str()).c_str(), (dest_path + "\\" + dest_it->c_str()).c_str()) == false) |
|
{ |
|
return false; |
|
} |
|
} |
|
//所有内容都相同,返回true |
|
if (src_it == src_files.end() && dest_it == dest_files.end()) |
|
{ |
|
return true; |
|
} |
|
return false; |
|
} |
|
else //同为file |
|
{ |
|
#ifdef DEBUG |
|
cout << "file compare" << endl; |
|
#endif |
|
return file_compare(src_path.c_str(), dest_path.c_str()); |
|
} |
|
} |
|
|
|
#ifdef DEBUG |
|
else { |
|
|
|
cout << src_path << " and " << dest_path << " not the same type!" << endl; |
|
} |
|
#endif |
|
return false; |
|
} |
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
vector<string> fs; |
|
list_dir(".", fs); |
|
for (vector<string>::iterator it = fs.begin(); it != fs.end(); it++) |
|
{ |
|
cout << *it << endl; |
|
} |
|
|
|
cout << file_compare("main.cpp", "main.cpp_cp") << endl;//1 |
|
cout << diff("main.cpp", "main.cpp_cp") << endl;//1 |
|
cout << diff("main.cpp", "not_main.cpp") << endl;//0 |
|
|
|
cout << is_dir(".") << endl;//1 |
|
cout << is_dir("..") << endl;//1 |
|
cout << is_dir("main.cpp") << endl;//1 |
|
cout << is_dir("nothing") << endl;//0 |
|
|
|
cout << file_exist(".") << endl;//1 |
|
cout << file_exist("nothing") << endl;//0 |
|
|
|
cout << diff("dir", "dir_cp") << endl;//1 |
|
cout << diff("dir", "not_dir") << endl;//0 |
|
getchar(); |
|
return 0; |
|
} |