#include "stdafx.h" #include <iostream.h> #include <fstream> #include <windows.h> #include <io.h> #include <tchar.h> // 将一个文件与另一个文件相比较, 相同返回TRUE,否则返回FALSE // lpszFilename1表示文件1的绝对路径,lpszFilename2表示文件2的绝对路径 BOOL CompareOneFileWithAnother(LPCTSTR lpszFilename1, LPCTSTR lpszFilename2) { #define Safe_CloseFile(p) {if (p!=NULL){fclose(p);p=NULL;}} BOOL bMatch = TRUE; // Check for existence // 如果其中一个文件不存在,返回FALSE if (_taccess(lpszFilename1, 0) != 0 || _taccess(lpszFilename2, 0) != 0) return FALSE; 如果文件为只读,去除文件1 lpszFilename1和文件2 lpszFilename2的只读属性 DWORD dwFileAttribute = 0; dwFileAttribute = GetFileAttributes(lpszFilename1); if (dwFileAttribute & FILE_ATTRIBUTE_READONLY) { DWORD flag = FILE_ATTRIBUTE_READONLY; flag =~flag; dwFileAttribute &= flag; SetFileAttributes(lpszFilename1,dwFileAttribute); } dwFileAttribute = GetFileAttributes(lpszFilename2); if (dwFileAttribute & FILE_ATTRIBUTE_READONLY) { DWORD flag = FILE_ATTRIBUTE_READONLY; flag =~flag; dwFileAttribute &= flag; SetFileAttributes(lpszFilename2,dwFileAttribute); } 如果文件为只读,去除文件1 lpszFilename1和文件2 lpszFilename2的只读属性 // #ifdef _UNICODE //处理宽字符 wstring strTmp1 = lpszFilename1; wstring strTmp2 = lpszFilename2; //转换 wide-char 为 char USES_CONVERSION; //string 转换为 char* 类型 const char *p1 = W2A(strTmp1.c_str()); const char *p2 = W2A(strTmp2.c_str()); #else const char *p1 = lpszFilename1; const char *p2 = lpszFilename2; #endif // // 读取文件长度 FILE *pfA = NULL; FILE *pfB = NULL; // 以字节的方式打开文件,并且允许读 pfA = fopen(p1, "rb"); pfB = fopen(p2, "rb"); if (pfA == NULL || pfB == NULL) { bMatch = FALSE; } else { //文件长度 long fileA_size = 0; long fileB_size = 0; //文件pfA的指针从起始位置0走到结束位置SEEK_END fseek( pfA, 0L, SEEK_END); //获取当前文件(pfA)的指针位置,结合上一个函数fseek获取文件长度fileA_size fileA_size = ftell(pfA); fseek( pfB, 0L, SEEK_END); fileB_size = ftell(pfB); if (fileA_size != fileB_size || fileA_size == 0) { bMatch = FALSE; } else { int i =0; size_t nSize = 0; int nShift = 0; // 左右移位次数, 如, nshift = 3, 1<<nshift is 8. //if (fileA_size == 0)return FALSE; // 如果文件大小小于等于512 bytes, 读取所有内容进行比较 if (fileA_size <= 1024) { DWORD Buffer[2][256] = {0}; // 256*sizeof(DWORD) = 1024 // 将指针定位到指定的文件位置(文件头),SEEK_SET表示文件头 fseek(pfA, 0, SEEK_SET); fseek(pfB, 0, SEEK_SET); // 从指定位置(文件头)读取数据保存到Buffer[0],数据长度为256*sizeof(DWORD) nSize = fread(Buffer[0], sizeof(char), 256*sizeof(DWORD), pfA); nSize = fread(Buffer[1], sizeof(char), 256*sizeof(DWORD), pfB); nSize = nSize>>2; for (i=0; i<nSize; i++) { // ^ 表示异或运算,相异为1,相同为0 if (Buffer[0][i] ^ Buffer[1][i]) { // 不相同,则返回 FALSE bMatch = FALSE; break; } } } else { if (fileA_size <= 1<<12) // 4*1024=4KB nShift = 2; // 比较4次 else if (fileA_size <= 1<<20) // 1024*1024 = 1MB nShift = 4; // 比较 16 次 else if (fileA_size <= 1<<26) // 1024*1024*64 = 64MB nShift = 5; // 比较 32 次 else nShift = 6; // 比较 64 次 DWORD Data[2][8] = {0}; DWORD nResult = 0; long nPos=0; // 当前位置 //long nOffSet = fileA_size >>nShift; long nOffSet = 8; int nMaxLoop = 1<<nShift; //for (i=0; i < nMaxLoop; i++) while(nPos+8<=fileA_size) { // 将指针定位到指定的文件位置(文件头),SEEK_SET表示文件头 fseek(pfA, nPos, SEEK_SET); fseek(pfB, nPos, SEEK_SET); // 从指定位置(文件头)读取数据保存到Data[0],数据长度为sizeof(Data[0]) nSize = fread(Data[0], sizeof(char), sizeof(Data[0]), pfA); nSize = fread(Data[1], sizeof(char), sizeof(Data[1]), pfB); // ^ 表示异或运算,相异为1,相同为0 // 异或运算8次 nResult = (Data[0][0] ^ Data[1][0])==0 ? 0 : 1; nResult += (Data[0][1] ^ Data[1][1])==0 ? 0 : 1; nResult += (Data[0][2] ^ Data[1][2])==0 ? 0 : 1; nResult += (Data[0][3] ^ Data[1][3])==0 ? 0 : 1; nResult += (Data[0][4] ^ Data[1][4])==0 ? 0 : 1; nResult += (Data[0][5] ^ Data[1][5])==0 ? 0 : 1; nResult += (Data[0][6] ^ Data[1][6])==0 ? 0 : 1; nResult += (Data[0][7] ^ Data[1][7])==0 ? 0 : 1; if (nResult != 0 ) { bMatch = FALSE; //break; } nPos += nOffSet; if (nPos >= fileA_size) //break; memset((void*)Data, 0, sizeof(Data)); } } } } // 关闭文件pfA Safe_CloseFile(pfA); // 关闭文件pfB Safe_CloseFile(pfB); return bMatch; } |