Skip to content

Instantly share code, notes, and snippets.

@lmatt-bit
Created October 26, 2010 09:26
比较两个路径所指内容是否相同
#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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment