急!求c++ builder 操作大文件的方法

liuyerits1234 2013-07-16 10:02:11
之前操作的txt档的大小一般不超过100M,所以直接用LoadFromFile的方法就可以直接读取文件,然后放入TStringList里再对数据进行处理分析,现在遇到了文件大小可能高达2GB这种,若用LoadFromFile的话就会出现Out of Memory

在网上搜寻了一下,知道有内存映射的方法,可是我还是疑问,内存映射到方法和分段的方法有什么区别,因为我开始是想先读一段,然后把这一段数据处理完,然后再读下一段,这样循环的,但是看了内存映射到方法思想好像和我想的不一样,我想请教一下内存映射读取了文件,如何对文件里的数据进行操作呢?

若是用分段的方法,那么又该如何分段呢?因为本身数据也是一块一块的
最好有使用内存映射或者分段的代码~

谢谢大家
...全文
313 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuyerits1234 2013-07-19
  • 打赏
  • 举报
回复
問題解決了~ 謝謝妖哥~
liuyerits1234 2013-07-18
  • 打赏
  • 举报
回复
还是有个问题, 我定义的dwTmpBlockByte=128*0x10000 //4MB pMem->Write之后可以看到pMem的Count是0x800000, 但是listTmp->LoadFromStream(pMem)之后 listTmp的大小才0x15000左右,而且每次还不一样,这是为什么啊? 求指教啊~
liuyerits1234 2013-07-18
  • 打赏
  • 举报
回复
找到原因了,应该在listTmp->LoadFromStream(pMem)之前将指针pMem指向0的位置; 加上pMem->Position=0就可以了
liuyerits1234 2013-07-18
  • 打赏
  • 举报
回复
引用 9 楼 ccrun 的回复:
创建一个TMemoryStream对象,通过Write方法将需要分析的数据地址和长度写入,再用TStringList对象LoadFromStream就可以了。
谢谢妖哥~ 可是我目前还是有个小问题,我的代码如下: TMemoryStream *pMem=new TMemoryStream(); pMem->Position=0; HANDLE mvFile=MapViewOfFile(mapFile,File_MAP_READ,0,dwFileOffsetLow, dwTmpBlockByte); TStringList *listTmp= new TStringList; pMem->Write((char*)mvFile+dwFileOffsetLow,dwTmpBlockByte);//debug时可以看到这里是Ok的 listTmp->LoadFromStream(pMem);//问题就出在这里,我Load进来却发现listTmp的Count是为0的, 求指教这是为什么啊?
ccrun.com 2013-07-18
  • 打赏
  • 举报
回复
Position置零(相当于指针移到开始)是好多人容易忽略的一个问题。 pMem->Write以后,看看Size属性是多少?是否和写入的长度相同?
ccrun.com 2013-07-17
  • 打赏
  • 举报
回复
创建一个TMemoryStream对象,通过Write方法将需要分析的数据地址和长度写入,再用TStringList对象LoadFromStream就可以了。
liuyerits1234 2013-07-17
  • 打赏
  • 举报
回复
我的意思是我由MapViewOfFile知道了地址,那么我总不能一个char一个char的读取数据然后做判断吧? 有没有一段一段的读的方法?因为我是想把这些数据根据\r\n分行存入TStringList中去
liuyerits1234 2013-07-17
  • 打赏
  • 举报
回复
引用 6 楼 guanchaoyi 的回复:
char *buf= new char 只分配了一个字节的空间,你想要更多的空间,应该要指定,如: char *buf= new char[64*1024]。 另外内存映射操作文件,也不必再做memcpy了吧,可以通过MapViewOfFile指定映射的部分来处理;
谢谢你,的确可以不用Memcpy,但是我还有问题想请教一下, 用MapViewOfFile指的地址可以来操作数据对吗? 例如 LPVOID lpBuffer = MapViewOfFile(hMap, FILE_MAP_READ, 0, dwFileOffsetLow, dwTmpBlockByte) char cTmp=(char)(&lpBuffer);这样就可以获得起始地址的值了吗? 那么如果我想获得一段数据的,该如何做呢?
关工 2013-07-17
  • 打赏
  • 举报
回复
char *buf= new char 只分配了一个字节的空间,你想要更多的空间,应该要指定,如: char *buf= new char[64*1024]。 另外内存映射操作文件,也不必再做memcpy了吧,可以通过MapViewOfFile指定映射的部分来处理;
liuyerits1234 2013-07-17
  • 打赏
  • 举报
回复
char *buf= new char,这样给char分配空间是可以的吧?
liuyerits1234 2013-07-17
  • 打赏
  • 举报
回复
引用 3 楼 sololie 的回复:
http://blog.csdn.net/xmnathan/article/details/6072858
看了,目前我还是有一个问题, 我先用了LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, dwFileOffsetLow, dwTmpBlockByte)的参数,然后会有memcpy(buf,(char*)lpBuffer+dwFileOffsetLow,dwTmpBlockByte) 此时dwTmpBlockByte如果超过了0x10000的时候调试就会Hang住, memcpy应该不只能copy 64kb吧, 求帮助~ 求好心人~
liuyerits1234 2013-07-16
  • 打赏
  • 举报
回复
刚刚用了一下内存映射的方法,出现一个问题,麻烦有人指导一下 //处理大文件 HANDLE hOpenFile=CreateFile(sfile.t_str(),FILE_READ_EA,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); if(hOpenFile!=Null) { ShowMessage("文件打开成功"); } else { ShowMessage("文件打开失败"); } int size=GetFileSize(hOpenFile,NULL); UnicodeString strtmp; ShowMessage(strtmp.sprintf(L"文件大小:%d",size)); HANDLE hFileMapping=CreateFileMapping(hOpenFile,NULL,PAGE_READONLY,0,0,NULL); if(hFileMapping!=0) { ShowMessage(“内存映射文件成功”); } else { ShowMessage(“内存映射文件失败”); } 问题就出在上面那句CreateFileMapping,得到了hFileMapping=NULL,那么内存映射失败了,这是怎么回事啊?
liuyerits1234 2013-07-16
  • 打赏
  • 举报
回复
没有人指教啊 我目前的想法是这样的 1.创建句柄:HANDLE hFile = CreateFile(sfile.t_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 2.获取文件大小:unsigned long mFileSize=GetFileSize(hFile,NULL); 3.创建文件映射:HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY , NULL, (DWORD)(mFileSize&0xffffffff), NULL); 4.读取映射中的内存:LPVOID lpBuffer = ::MapViewOfFile(hMap, FILE_MAP_READ, NULL, NULL, mFileSize); 我想问一下MapViewOfFile中的参数dwFileOffsetHigh,dwFileOffsetLow设置为NULL有什么影响没?是根据什么设置这两个参数的,还有dwNumberOfBytesToMap这个参数我设置为文件的大小有没有关系啊,这样是否代表映射整个文件? 求高手,谢谢啦
内容概要:本文围绕“非线性流量的数据驱动Koopman模型预测控制研究”展开,提出一种基于数据驱动的Koopman算子理论方法,用于构建非线性系统的线性化状态空间模型,并结合模型预测控制(MPC)实现对复杂非线性系统的高效控制。研究通过引入扩展动态模态分解(EDMD)等观测函数,将非线性动力学映射至高维特征空间,在该空间中实现近似线性化表征,进而融合线性MPC框架进行优化解。全文系统阐述了Koopman算子的数学基础、隐式线性化机制及在非线性流量控制中的建模流程,并通过Matlab代码完成了算法实现与仿真实验,验证了该方法在处理无精确物理模型、强非线性、时变动态系统中的有效性与鲁棒性,尤其适用于工业流程控制、能源系统调度等实际工程场景。; 适合人群:具备自动控制理论、非线性系统分析基础,熟悉Matlab编程,从事控制工程、系统辨识、智能优化、能源系统建模等方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于难以建立精确数学模型的复杂非线性系统(如流体动力系统、电力电子系统、机器人动力学等)的建模与实时控制;②实现数据驱动下的模型预测控制,提升系统响应速度与控制精度;③为先进控制策略(如MPC)提供一种可行的线性化建模范式,推动现代控制理论与数据科学、机器学习的深度融合。; 阅读建议:建议读者结合提供的Matlab代码深入理解Koopman方法的具体实现过程,重点关注观测函数构造、核函数选择、矩阵逼近、降维处理及MPC控制器设计等关键技术环节,并尝试将其迁移至其他非线性系统中进行复现实验与性能对比,以全面掌握其适用范围与局限性。
内容概要:本文详细介绍了一种基于Simulink的光伏储能单相逆变器并网仿真模型,系统涵盖了光伏阵列、储能单元、DC-AC单相逆变器及并网接口的完整结构,重点实现了储能环节的能量管理与逆变器并网控制策略的建模仿真。通过Simulink平台构建系统模型,验证了逆变器输出电能质量、并网稳定性以及控制系统的动态响应性能,采用SPWM调制、PI闭环控制等关键技术,确保并网电流与电网电压同频同相,满足并网电能质量要。该模型不仅可用于分布式能源系统的仿真研究,还可作为新能源并网技术的教学与工程实践工具。; 适合人群:电气工程、自动化、新能源科学与工程等相关专业的高校本科生、研究生、科研人员,以及从事光伏发电系统设计、储能控制与并网技术研发的工程技术人员。; 使用场景及目标:①深入理解光伏储能系统中能量转换、存储与并网控制的整体工作原理;②支持课程设计、毕业设计或科研项目中对单相逆变器控制策略(如SPWM、PI调节、锁相技术等)的仿真验证与参数优化;③为后续研究更复杂的控制算法(如MPPT、低电压穿越、谐波抑制等)提供可扩展的仿真基础平台。; 阅读建议:建议结合MATLAB/Simulink环境动手搭建与调试模型,逐步理解各模块(如光伏建模、储能充放电控制、逆变器驱动、锁相环、PI调节器等)的功能与交互关系,重点关注控制系统的设计逻辑与参数整定过程,并可通过修改负载条件或电网参数测试系统鲁棒性,为进一步拓展至三相系统或多机并网场景奠定基础。

1,222

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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