VC中比较两个文件是否内容相等

来源:互联网 发布:时时彩选号软件 编辑:程序博客网 时间:2024/06/15 19:56

#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;
}

 
原创粉丝点击