内存映射 处理大txt

土土 2012-02-15 03:00:55
我对一个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("成功完成对文件的访问");
}


...全文
181 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
土土 2012-02-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 gameslq 的回复:]
>>我对一个txt进行内存映射后,想把文件内容读到CString里然后进行处理,请问怎么读;
或者是我思路错了,不能读到CString里应该直接处理,可是应该怎么处理呢,比如排序后删除重复的。比如查找某个字符
是有格式的文件 还是无序的?
如果是有格式的,可以考虑放到数据库中进行处理
[/Quote]
就是小说一类的 有逗号 按逗号隔开!
gameslq 2012-02-15
  • 打赏
  • 举报
回复
>>我对一个txt进行内存映射后,想把文件内容读到CString里然后进行处理,请问怎么读;
或者是我思路错了,不能读到CString里应该直接处理,可是应该怎么处理呢,比如排序后删除重复的。比如查找某个字符
是有格式的文件 还是无序的?
如果是有格式的,可以考虑放到数据库中进行处理


oyljerry 2012-02-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 bujanbusan 的回复:]
我现在读出来了是byte的 可是怎么转化成汉字呢?读出得结果有数字也有汉字 例如4919622744 其实txt 里是 1你, 这样怎么传化为CString?就是将4919622744转化为 1你,
[/Quote]
文件内容保存为unicode格式,然后读取的时候用unicode方式去读取,CStdIoString等都可以按行读取
土土 2012-02-15
  • 打赏
  • 举报
回复
我现在读出来了是byte的 可是怎么转化成汉字呢?读出得结果有数字也有汉字 例如4919622744 其实txt 里是 1你, 这样怎么传化为CString?就是将4919622744转化为 1你,
kyotrue 2012-02-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bujanbusan 的回复:]
引用 1 楼 kyotrue 的回复:
假设你的文本编码格式与程序一致,那么如果映射的是中间一段,查找"\r\n"断行就行了,一行的内容总是可以直接转成CString的,而被截断的行是不可读的。

我想 读取所有的内容到CString啊
[/Quote]

除非你的TXT是使用UNICODE方式编码的,这样会按2字节对齐,只要你保证映射的偏移是偶数,而且有多少字符也是确定的,这样就能够全部直接转换成CString,CString有很多构造函数,有一个可以直接指定地址、字符个数的。

如果不是UNICODE编码的,那么想要全部读出是不可能的,万一你映射地址的开始字节刚好只有一个字符的一半数据呢,另一半数据都没映射进来,你要怎么全部读出来?而且你不通过换行符也无法判断第一个完整的字符是从哪儿开始的。
土土 2012-02-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ouyh12345 的回复:]
用std::string
把映射到的内容转为char*,并拷贝到string
[/Quote]
请问具体代码怎么写呢? 我还是不大明白这个文件映射!
ouyh12345 2012-02-15
  • 打赏
  • 举报
回复
用std::string
把映射到的内容转为char*,并拷贝到string
土土 2012-02-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 kyotrue 的回复:]
假设你的文本编码格式与程序一致,那么如果映射的是中间一段,查找"\r\n"断行就行了,一行的内容总是可以直接转成CString的,而被截断的行是不可读的。
[/Quote]
我想 读取所有的内容到CString啊
kyotrue 2012-02-15
  • 打赏
  • 举报
回复
假设你的文本编码格式与程序一致,那么如果映射的是中间一段,查找"\r\n"断行就行了,一行的内容总是可以直接转成CString的,而被截断的行是不可读的。

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧