目的:统计指定目录下的所有文件,以固定格式写入文本文件
读取指定的文本文件,因为需要和其他文件进行对比,得出改变的的文件。
问题:用的是API来读取文件,一个方法是将所有文本的内容读取到缓存当中,而且进行解析的话,得一行一行读取,API没提供方便的函数,使用READFILE只能一个一个字符的读取 ,遇到0X0D,0X0A换行,而且要进行对比的话,很不方便。用C++ ifstream来实现文件的读写,读取ASCII文本正常,如何读取UNICODE文本?
文本文件大概是这样的:
11/18/2008 1:41:11 3/3/2006 15:23:22 26877 AccCtrl.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:22:12 2877 access.idl D:\Include\
11/18/2008 1:41:11 3/3/2006 15:23:22 18896 AclAPI.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:23:22 10116 AclUI.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:19:32 383778 activdbg.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:22: 4 627 activecf.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:23:12 1161 ActiveDS.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:23:22 121263 ActivScp.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:23:22 31060 ActivScp.Idl D:\Include\
11/18/2008 1:41:11 3/3/2006 15:22:12 3381 adc.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:23:14 17670 Admex.h D:\Include\
11/18/2008 1:41:11 3/3/2006 15:22:12 197572 adoctint.h D:\Include\
我的想法是按行读取后,用MAP存储,存储读取本文件和远程下载的文本文件,接下来就是做字符串比较了,然后将有改动的文件保存下来,
有没更好的方法?谢谢
测试代码:#include <tchar.h>
#include <fstream>
#include <Windows.h>
#include <vector>
#include <string>
#include <iostream>
using namespace std;#define BUFSIZE 4096
#define LINEMAX 125
#define MAXSIZE 256
#define MAX_SIZE_TO_READ 1024*1024
#define FILE_PATH _T("D:\\Include\\")
struct USER_DEFINE_FIND_DATA : public WIN32_FIND_DATA
{
TCHAR strFilePath[MAXSIZE]; USER_DEFINE_FIND_DATA();
};USER_DEFINE_FIND_DATA::USER_DEFINE_FIND_DATA()
{
ZeroMemory(strFilePath,sizeof(TCHAR)*MAXSIZE);
}static std::vector<USER_DEFINE_FIND_DATA> gsFileInfo;VOID RecurseDirectory(TCHAR* strDir);
BOOL Win32WriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite = LINEMAX,DWORD dwNumberOfBytesWritten = 0);
VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo);
VOID Win32ReadFromText(TCHAR *strReadBuf);
VOID ReadAsciiFile(TCHAR* strFileName);int _tmain()
{
RecurseDirectory(FILE_PATH);
Win32WriteToText(gsFileInfo);
ReadAsciiFile(_T("D:\\Include\\update\\update.txt"));
return 0;
}VOID RecurseDirectory(TCHAR* strDir)
{
TCHAR szTemp[MAXSIZE];
ZeroMemory(szTemp,sizeof(TCHAR)*MAXSIZE);
DWORD dwPos = 0;
HANDLE hFindFile = INVALID_HANDLE_VALUE;
USER_DEFINE_FIND_DATA Filedata;
ZeroMemory(&Filedata,sizeof(Filedata));
TCHAR *strPathName = new TCHAR[BUFSIZE];
TCHAR *strTempPath = new TCHAR[BUFSIZE];
BOOL bSearchFile = FALSE;
BOOL bFinished = FALSE; wcscpy(strPathName,strDir);
if (strPathName[wcslen(strPathName)-1] != _T('\\'))
{
wcscat(strPathName,_T("\\"));
}
wcscat(strPathName,_T("*.*"));
bSearchFile = (INVALID_HANDLE_VALUE !=(hFindFile = FindFirstFile(strPathName,&Filedata)));
if (bSearchFile)
{
if (wcscmp(Filedata.cFileName,_T(".")) && wcscmp(Filedata.cFileName,_T("..")))
{
wprintf(_T(" %s\n"),Filedata.cFileName);
}
while (!bFinished)
{
if (FindNextFile(hFindFile,&Filedata))
{
if ((Filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && wcscmp(Filedata.cFileName,_T(".")) && wcscmp(Filedata.cFileName,_T("..")))
{
wcscpy(strTempPath,strDir);
wcscat(strTempPath,Filedata.cFileName);
wcscat(strTempPath,_T("\\"));
wprintf(_T(" %s\n"),Filedata.cFileName);
wcscpy(Filedata.strFilePath,strTempPath);
gsFileInfo.push_back(Filedata);
RecurseDirectory(strTempPath);
}
else if (wcscmp(Filedata.cFileName,_T(".")) && wcscmp(Filedata.cFileName,_T("..")))
{
wprintf(_T(" %s\n"),Filedata.cFileName);
wcscpy(Filedata.strFilePath,strDir);
gsFileInfo.push_back(Filedata);
}
}
else
{
if( GetLastError() == ERROR_NO_MORE_FILES )
{
bFinished = TRUE;
}
else
{
bFinished = TRUE;
}
}
}
}
else
{
wprintf (_T("Invalid File Handle. GetLastError reports %d\n"), GetLastError ());
}
delete []strPathName;
delete []strTempPath;
FindClose(hFindFile);
}BOOL Win32WriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten )
{
if (!WriteFile(hHandle,strBuffer,dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite,NULL))
{
wprintf (_T("WriteFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo)
{
DWORD dwByteWrite = 0;
SYSTEMTIME systemCreateTime;
SYSTEMTIME systemChangeTime;
FILETIME fileCreateTime;
FILETIME fileLastChageTime;
TCHAR szTemp[MAXSIZE];
ZeroMemory(szTemp,sizeof(TCHAR)*MAXSIZE);
ZeroMemory(&systemCreateTime,sizeof(systemCreateTime));
ZeroMemory(&fileCreateTime,sizeof(fileCreateTime));
ZeroMemory(&fileLastChageTime,sizeof(fileLastChageTime));
ZeroMemory(&systemChangeTime,sizeof(systemChangeTime)); HANDLE hFile = CreateFile(_T("D:\\Include\\update\\update.txt"),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if (INVALID_HANDLE_VALUE == hFile)
{
wprintf(_T("CreateFile failed at %d\n"),GetLastError());
return;
}
for (int i = 0;i < gsFileInfo.size();i++ )
{
fileCreateTime = vFileInfo[i].ftCreationTime;
fileLastChageTime = vFileInfo[i].ftLastWriteTime;
if (!FileTimeToSystemTime(&fileCreateTime,&systemCreateTime))
{
wprintf(_T("fileCreateTime FileTimeToSystemTime failed at %d\n"),GetLastError());
}
if (!FileTimeToSystemTime(&fileLastChageTime,&systemChangeTime))
{
wprintf(_T("fileLastChageTime FileTimeToSystemTime failed at %d\n"),GetLastError());
}
swprintf(szTemp,sizeof(szTemp),_T("%2d/%2d/%4d %2d:%2d:%2d %2d/%2d/%4d %2d:%2d:%2d %8d %30s %20s\r\n" ),systemCreateTime.wMonth,systemCreateTime.wDay,
systemCreateTime.wYear,systemCreateTime.wHour,systemCreateTime.wMinute,systemCreateTime.wSecond,
systemChangeTime.wMonth,systemChangeTime.wDay,systemChangeTime.wYear,systemChangeTime.wHour,systemChangeTime.wMinute,systemChangeTime.wSecond,
gsFileInfo[i].nFileSizeLow,gsFileInfo[i].cFileName,gsFileInfo[i].strFilePath);
Win32WriteFile(hFile,szTemp,wcslen(szTemp)*2,dwByteWrite);
}
CloseHandle(hFile);
}VOID Win32ReadFromText(TCHAR *strReadBuf)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL bResult = FALSE;
DWORD dwNumberOfBytesToRead = MAX_SIZE_TO_READ;
DWORD dwNumberOfBytesRead = 0;
hFile = CreateFile(_T("D:\\Include\\update\\update.txt"),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
bResult = ReadFile(hFile,strReadBuf,dwNumberOfBytesToRead,&dwNumberOfBytesRead,NULL);
if (!bResult)
{
wprintf(_T("ReadFile failed at %d\n"),GetLastError());
return;
}
CloseHandle(hFile);
}VOID ReadAsciiFile(TCHAR* strFileName)
{
ifstream ifs(strFileName);
string strRead;
while (!ifs.eof())
{
getline(ifs,strRead);
}
}
解决方案 »
- CDateTimeCtrl时间控件下拉时只能选择日期,不能选择时间。能否设置成日期和时间并存?
- 求助关于SNMP++trap接收的问题
- 如何实现QQ上的截屏功能?
- listctrl显示文字问题
- VC操作数据库时说'CRecordSet' : undeclared identifier
- ip 组播通讯出现!!!
- 出错怎会在这里呢?请帮忙看一下我的程序?
- 高分讨论: 双缓冲绘制客户区效率低下的问题。
- 请问一下,如何用属性页实现向导,最好有例子代码,谢谢大家,急需
- 100分求 2002年中级程序员考试 模拟试题,分数可以增加!
- 这种情况下,我应该使用一个套节字呢,还是使用多个?
- vs2005中有prifile吗
#include <comdef.h>
char *str1 = "hello中国人!";
WCHAR *str2 = _bstr_t(str1);
不然得全部转换为ASCII版本
通过流来读取也是样的。每次读1个字节,然后读2个字节后就处理一下。很麻烦么?
可能有些情况你需要判断处理一下。这个是不可避免的!!!其实你仔细分析下。就感觉很easy的。就那么几中情况特殊点。
bool GetFileData(const char* filePath,PBYTE& sourValue)
{
char isUnicode[2];//专用于判断是否unicode文件 DWORD fileLen; //文件长度
DWORD dwCount; //实际读取出的数据量 FILE *hSource; //文件
if (!(hSource=fopen(filePath,_T("rb"))))
{
return false;
} fseek(hSource,0,SEEK_END);
fileLen=ftell(hSource);
fseek(hSource,0,SEEK_SET);
//判断文件类型(ANSI或UNICODE) fread(isUnicode, 1, 2, hSource);
fseek(hSource,0,SEEK_SET);
//UNICODE格式
if( isUnicode[0] == '\xff' && isUnicode[1] == '\xfe')
{
fseek(hSource,2,SEEK_SET);//跳过两个字节Unicode标识再处理
LPWSTR pwbBuffer=new WCHAR[fileLen]; dwCount = fread(pwbBuffer, 1, fileLen, hSource); if(ferror(hSource))
{
return false;
} //Unicode转换Ansi处理(适用于一般性文本)
//----------------
DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,pwbBuffer,-1,NULL,0,NULL,FALSE);//计算要使用空间
dwCount=dwNum;//unicode返回的值要是转换后的大小 if(!(sourValue = (BYTE *)malloc(dwNum)))
{
return false;
} WideCharToMultiByte (CP_OEMCP,NULL,pwbBuffer,-1,(PCHAR)sourValue,dwNum,NULL,FALSE);
//--------------- delete[] pwbBuffer; }else{
//...........Ansi处理
}
fclose(hSource); return true;
}
目前把代码转换成了兼容UNICODE 和ASCII两个版本了,考虑效率问题和一般的习惯,还是UNICODE 版本比较好。先把后续的工作先完成吧
#include <tchar.h>
#include <fstream>
#include <Windows.h>
#include <vector>
#include <string>
#include <iostream>
#include <map>
using namespace std;#define BUFSIZE 4096
#define LINEMAX 125
#define MAXSIZE 256
#define MAX_SIZE_TO_READ 1024*1024
#define FILE_PATH _T("D:\\Include\\")
struct USER_DEFINE_FIND_DATA : public WIN32_FIND_DATA
{
TCHAR strFilePath[MAXSIZE]; USER_DEFINE_FIND_DATA();
};USER_DEFINE_FIND_DATA::USER_DEFINE_FIND_DATA()
{
ZeroMemory(strFilePath,sizeof(TCHAR)*MAXSIZE);
}// global variable
static vector<USER_DEFINE_FIND_DATA> gsFileInfo;
static map <int, string> gsMap;
map <int, string>::iterator g_pIter;
typedef pair <int, string> Int_Pair;
static vector<vector<TCHAR>> gsVec1;
static vector<vector<vector<TCHAR>>> gsVec4;
static vector <TCHAR> gsVec2;
static vector <TCHAR> gsVec3;
int gCh = _T(',');//function declaration.
VOID RecurseDirectory(TCHAR* strDir);
BOOL Win32WriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite = LINEMAX,DWORD dwNumberOfBytesWritten = 0);
VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo);
VOID Win32ReadFromText(TCHAR *strReadBuf);
VOID ReadAsciiFile(TCHAR* strFileName);
vector<vector<TCHAR>> ParseString(TCHAR* strTemp);//just a test
int _tmain()
{
vector<vector<TCHAR>> vTemp;
RecurseDirectory(FILE_PATH);
Win32WriteToText(gsFileInfo);
ReadAsciiFile(_T("D:\\Include\\update\\update.txt"));
for (g_pIter = gsMap.begin();g_pIter != gsMap.end(); g_pIter ++)
{
vTemp = ParseString(const_cast<char*>(g_pIter->second.c_str()));
gsVec4.push_back(vTemp);
}
return 0;
}VOID RecurseDirectory(TCHAR* strDir)
{
TCHAR szTemp[MAXSIZE];
ZeroMemory(szTemp,sizeof(TCHAR)*MAXSIZE);
DWORD dwPos = 0;
HANDLE hFindFile = INVALID_HANDLE_VALUE;
USER_DEFINE_FIND_DATA Filedata;
ZeroMemory(&Filedata,sizeof(Filedata));
TCHAR *strPathName = new TCHAR[BUFSIZE];
TCHAR *strTempPath = new TCHAR[BUFSIZE];
BOOL bSearchFile = FALSE;
BOOL bFinished = FALSE; _tcscpy(strPathName,strDir);
if (strPathName[_tcslen(strPathName)-1] != _T('\\'))
{
_tcscat(strPathName,_T("\\"));
}
_tcscat(strPathName,_T("*.*"));
bSearchFile = (INVALID_HANDLE_VALUE !=(hFindFile = FindFirstFile(strPathName,&Filedata)));
if (bSearchFile)
{
if (_tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
_tprintf(_T(" %s\n"),Filedata.cFileName);
}
while (!bFinished)
{
if (FindNextFile(hFindFile,&Filedata))
{
if ((Filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && _tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
_tcscpy(strTempPath,strDir);
_tcscat(strTempPath,Filedata.cFileName);
_tcscat(strTempPath,_T("\\"));
_tprintf(_T(" %s\n"),Filedata.cFileName);
_tcscpy(Filedata.strFilePath,strTempPath);
_tcscat(Filedata.strFilePath,Filedata.cFileName);
gsFileInfo.push_back(Filedata);
RecurseDirectory(strTempPath);
}
else if (_tcscmp(Filedata.cFileName,_T(".")) && _tcscmp(Filedata.cFileName,_T("..")))
{
_tprintf(_T(" %s\n"),Filedata.cFileName);
_tcscpy(Filedata.strFilePath,strDir);
_tcscat(Filedata.strFilePath,Filedata.cFileName);
gsFileInfo.push_back(Filedata);
}
}
else
{
if( GetLastError() == ERROR_NO_MORE_FILES )
{
bFinished = TRUE;
}
else
{
bFinished = TRUE;
}
}
}
}
else
{
_tprintf (_T("Invalid File Handle. GetLastError reports %d\n"), GetLastError ());
}
delete []strPathName;
delete []strTempPath;
FindClose(hFindFile);
}BOOL Win32WriteFile(HANDLE hHandle,LPCTSTR strBuffer,DWORD dwNumberOfBytesToWrite,DWORD dwNumberOfBytesWritten )
{
if (!WriteFile(hHandle,strBuffer,dwNumberOfBytesToWrite,&dwNumberOfBytesToWrite,NULL))
{
_tprintf (_T("WriteFile failed at %d\n"),GetLastError());
return FALSE;
}
return TRUE;
}VOID Win32WriteToText(std::vector<USER_DEFINE_FIND_DATA> vFileInfo)
{
DWORD dwByteWrite = 0;
SYSTEMTIME systemCreateTime;
SYSTEMTIME systemChangeTime;
FILETIME fileCreateTime;
FILETIME fileLastChageTime;
TCHAR szTemp[MAXSIZE];
ZeroMemory(szTemp,sizeof(TCHAR)*MAXSIZE);
ZeroMemory(&systemCreateTime,sizeof(systemCreateTime));
ZeroMemory(&fileCreateTime,sizeof(fileCreateTime));
ZeroMemory(&fileLastChageTime,sizeof(fileLastChageTime));
ZeroMemory(&systemChangeTime,sizeof(systemChangeTime)); HANDLE hFile = CreateFile(_T("D:\\Include\\update\\update.txt"),GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if (INVALID_HANDLE_VALUE == hFile)
{
_tprintf(_T("CreateFile failed at %d\n"),GetLastError());
return;
}
for (int i = 0;i < gsFileInfo.size();i++ )
{
fileCreateTime = vFileInfo[i].ftCreationTime;
fileLastChageTime = vFileInfo[i].ftLastWriteTime;
if (!FileTimeToSystemTime(&fileCreateTime,&systemCreateTime))
{
_tprintf(_T("fileCreateTime FileTimeToSystemTime failed at %d\n"),GetLastError());
}
if (!FileTimeToSystemTime(&fileLastChageTime,&systemChangeTime))
{
_tprintf(_T("fileLastChageTime FileTimeToSystemTime failed at %d\n"),GetLastError());
} //Unicode version
//swprintf(szTemp,sizeof(szTemp),_T("%2d/%2d/%4d %2d:%2d:%2d %2d/%2d/%4d %2d:%2d:%2d %8d %30s %20s\r\n" ),systemCreateTime.wMonth,systemCreateTime.wDay,
// systemCreateTime.wYear,systemCreateTime.wHour,systemCreateTime.wMinute,systemCreateTime.wSecond,
// systemChangeTime.wMonth,systemChangeTime.wDay,systemChangeTime.wYear,systemChangeTime.wHour,systemChangeTime.wMinute,systemChangeTime.wSecond,
// gsFileInfo[i].nFileSizeLow,gsFileInfo[i].cFileName,gsFileInfo[i].strFilePath); // Ascii version
_stprintf(szTemp,_T("%d/%d/%d--%d:%d:%d,%d/%d/%d--%d:%d:%d,%d,%s,\r\n" ),systemCreateTime.wMonth,systemCreateTime.wDay,
systemCreateTime.wYear,systemCreateTime.wHour,systemCreateTime.wMinute,systemCreateTime.wSecond,
systemChangeTime.wMonth,systemChangeTime.wDay,systemChangeTime.wYear,systemChangeTime.wHour,systemChangeTime.wMinute,systemChangeTime.wSecond,
gsFileInfo[i].nFileSizeLow,gsFileInfo[i].strFilePath); //Unicode version
//Win32WriteFile(hFile,szTemp,_tcslen(szTemp)*2,dwByteWrite); // Ascii version
Win32WriteFile(hFile,szTemp,_tcslen(szTemp),dwByteWrite);
}
CloseHandle(hFile);
}VOID Win32ReadFromText(TCHAR *strReadBuf)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL bResult = FALSE;
DWORD dwNumberOfBytesToRead = MAX_SIZE_TO_READ;
DWORD dwNumberOfBytesRead = 0;
hFile = CreateFile(_T("D:\\Include\\update\\update.txt"),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
bResult = ReadFile(hFile,strReadBuf,dwNumberOfBytesToRead,&dwNumberOfBytesRead,NULL);
if (!bResult)
{
_tprintf(_T("ReadFile failed at %d\n"),GetLastError());
return;
}
CloseHandle(hFile);
}
VOID ReadAsciiFile(TCHAR* strFileName)
{
int iCoutn = 0;
ifstream ifs(strFileName);
string strRead;
while (!ifs.eof())
{
iCoutn ++;
getline(ifs,strRead);
gsMap.insert(Int_Pair(iCoutn,strRead));
}
ifs.close();
}vector<vector<TCHAR>> ParseString(TCHAR* strTemp)
{
int result;
TCHAR *pdest;
// Search forward.
while (1)
{
pdest = strchr( strTemp, gCh );
//if not ch find ,return
if (pdest == NULL)
{
return gsVec1;
}
//the position of which you first find the char ch
result = (int)(pdest - strTemp + 1);
//push the string of temp to vector;
for (int m = 0;m < result - 1 ; m++)
{
gsVec3.push_back(strTemp[m]);
}
//push the vector<char> to vector<vector<char>>
gsVec1.push_back(gsVec3);
gsVec3.erase(gsVec3.begin(),gsVec3.end());
if ( pdest != NULL )
{
_tprintf( _T("Result: first %c found at position %d\n"),
gCh, result );
}
else
{
_tprintf( "Result: %c not found\n" );
}
int iLen = strlen(pdest); if (gsVec2.size() != 0)
{
gsVec2.erase(gsVec2.begin(),gsVec2.end());
}
for (int i = 1 ;i < iLen ; i++)
{
gsVec2.push_back(pdest[i]);
} int nLen = strlen(strTemp);
for (int k = 0;k < nLen ; k++)
{
strTemp[k] = 0;
}
for (int j = 0;j < gsVec2.size();j++)
{
strTemp[j] = gsVec2[j];
}
}
return gsVec1;
}