我对一个txt进行内存映射后,想把文件内容读到CString里然后进行处理,请问怎么读;
或者是我思路错了,不能读到CString里应该直接处理,可是应该怎么处理呢,比如排序后删除重复的。比如查找某个字符
西面是代码
CFileDialog fileDlg(TRUE, "*.txt", "*.txt", NULL, "文本文件 (*.txt)|*.txt||", this);
fileDlg.m_ofn.Flags |= OFN_FILEMUSTEXIST;
fileDlg.m_ofn.lpstrTitle = "通过内存映射文件读取数据";
if (fileDlg.DoModal() == IDOK)
{
//创建文件对象
HANDLE hFile = CreateFile(fileDlg.GetPathName(), GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
TRACE("创建文件对象失败,错误代码:%drn", GetLastError());
return;
}
//创建文件映射对象
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
if (hFileMap == NULL)
{
TRACE("创建文件映射对象失败,错误代码:%drn", GetLastError());
return;
}
//得到系统分配粒度
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD dwGran = SysInfo.dwAllocationGranularity;
//得到文件尺寸
DWORD dwFileSizeHigh;
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
//关闭文件对象
CloseHandle(hFile);
//偏移地址
__int64 qwFileOffset = 0;
//块大小
DWORD dwBlockBytes = 1000 * dwGran;
if (qwFileSize < 1000 * dwGran)
dwBlockBytes = (DWORD)qwFileSize;
while (qwFileOffset > 0)
{
//映射视图
LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,
(DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),
dwBlockBytes);
if (lpbMapAddress == NULL)
{
TRACE("映射文件映射失败,错误代码:%drn", GetLastError());
return;
}
//对映射的视图进行访问
for(DWORD i = 0; i < dwBlockBytes; i++)
BYTE temp = *(lpbMapAddress + i);//撤消文件映像
UnmapViewOfFile(lpbMapAddress);
//修正参数
qwFileOffset += dwBlockBytes;
qwFileSize -= dwBlockBytes;
}
//关闭文件映射对象句柄
CloseHandle(hFileMap);
AfxMessageBox("成功完成对文件的访问");
}
或者是我思路错了,不能读到CString里应该直接处理,可是应该怎么处理呢,比如排序后删除重复的。比如查找某个字符
西面是代码
CFileDialog fileDlg(TRUE, "*.txt", "*.txt", NULL, "文本文件 (*.txt)|*.txt||", this);
fileDlg.m_ofn.Flags |= OFN_FILEMUSTEXIST;
fileDlg.m_ofn.lpstrTitle = "通过内存映射文件读取数据";
if (fileDlg.DoModal() == IDOK)
{
//创建文件对象
HANDLE hFile = CreateFile(fileDlg.GetPathName(), GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
TRACE("创建文件对象失败,错误代码:%drn", GetLastError());
return;
}
//创建文件映射对象
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
if (hFileMap == NULL)
{
TRACE("创建文件映射对象失败,错误代码:%drn", GetLastError());
return;
}
//得到系统分配粒度
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD dwGran = SysInfo.dwAllocationGranularity;
//得到文件尺寸
DWORD dwFileSizeHigh;
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize |= (((__int64)dwFileSizeHigh) << 32);
//关闭文件对象
CloseHandle(hFile);
//偏移地址
__int64 qwFileOffset = 0;
//块大小
DWORD dwBlockBytes = 1000 * dwGran;
if (qwFileSize < 1000 * dwGran)
dwBlockBytes = (DWORD)qwFileSize;
while (qwFileOffset > 0)
{
//映射视图
LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,
(DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),
dwBlockBytes);
if (lpbMapAddress == NULL)
{
TRACE("映射文件映射失败,错误代码:%drn", GetLastError());
return;
}
//对映射的视图进行访问
for(DWORD i = 0; i < dwBlockBytes; i++)
BYTE temp = *(lpbMapAddress + i);//撤消文件映像
UnmapViewOfFile(lpbMapAddress);
//修正参数
qwFileOffset += dwBlockBytes;
qwFileSize -= dwBlockBytes;
}
//关闭文件映射对象句柄
CloseHandle(hFileMap);
AfxMessageBox("成功完成对文件的访问");
}
把映射到的内容转为char*,并拷贝到string
除非你的TXT是使用UNICODE方式编码的,这样会按2字节对齐,只要你保证映射的偏移是偶数,而且有多少字符也是确定的,这样就能够全部直接转换成CString,CString有很多构造函数,有一个可以直接指定地址、字符个数的。如果不是UNICODE编码的,那么想要全部读出是不可能的,万一你映射地址的开始字节刚好只有一个字符的一半数据呢,另一半数据都没映射进来,你要怎么全部读出来?而且你不通过换行符也无法判断第一个完整的字符是从哪儿开始的。
或者是我思路错了,不能读到CString里应该直接处理,可是应该怎么处理呢,比如排序后删除重复的。比如查找某个字符
是有格式的文件 还是无序的?
如果是有格式的,可以考虑放到数据库中进行处理