7605|14

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

Wince 下使用内存映射读取大文件问题 [复制链接]


这个问题折磨我2天,现求助于大家,谢谢了。
代码如下(基于C# / .net ce framework的):
iptr = PIvoke.CreateFileForMapping(filename, GENERIC_READ, FILE_READ_ONLY, IntPtr.Zero,
                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RADOM_ACCESS , IntPtr.Zero);

                hmapping = PIvoke.CreateFileMapping(iptr, IntPtr.Zero, PROTECTION_READ_ONLY, 0, 4 * 1024 * 1024, name);

                hview = PIvoke.MapViewOfFile(hmapping, FILE_MAP_READ, 0, 0, 0);

                    for(;i                         b = Marshal.ReadByte(hview,(int)i);

输入的文件大小为190M,但是实际上能读取的仅为 4 * 1024 * 1024, 如果把  CreateFileMapping的4 * 1024 * 1024 改成更大或者改成 0( msdn说0时大小为文件的真实大小),运行到这就会得到 Not enough storage is available to process this command.  错误,(用GetLastError获得的返回值 8。)

这里我需要什么样的操作才能读取后面部分的文件? 或者在现有的基础上做什么改动?或者有什么其他解决方案? 非常感谢。100分不够还可以加。
====
给出C++/C#的任何代码实例或者解释都行,谢谢了。

最新回复

非常感谢大家的回复。 最后的结果是:不要求读那么大的文件了。 另外根据这几天的经验,在模拟器上和真实设备上的区别也是挺大的。还有就是内存的分配设置也有影响。 揭帖。谢谢大家了。  详情 回复 发表于 2007-9-24 11:52
点赞 关注

回复
举报

66

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
一是申请足够的空间,将文件中的内容以4 * 1024 * 1024为一段,一段一段地读出来;
或者直接读出一段来,进行对应操作,再继续读下一段内容。

char buff[100][4*1024*1024];

hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
         SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
        for (int i = 0; i < 100; i ++)
        {                       
               ReadFile(hFile, &buff, 4*1024*1024, &dwReadNum, NULL);
                //添加操作代码
        }
        CloseHandle(hFile);
}
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
谢谢楼上的,可是这不是我想要的啊。
我想要的是在wince 下,用内存映射读取大文件的问题。谢谢了。

继续期待高手
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

4
 
wince 恐怕没有那么多资源分配给你,因为wince每个进程的虚拟内存很小。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
有个磁盘调度和内存读取的问题。所以,实际内存里的文件大小未必为实际文件大小。
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

6
 
恩,那有什么办法能够读取这么大的文件呢,查了好多资料,都是说用内存映射,CreateFileForMapping, CreateFileMapping, 这几个方法都是用于内存映射的,小文件没有问题,大文件就出错了。

继续等待,谢谢了。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

7
 
MapViewOfFile好像可以根据位置长度来分配的,大小好像是64K的倍数,具体大小需要用API来得一下
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

8
 
google一下吧,上次我google到的试了还行
 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

9
 
//创建文件
        HANDLE hFile = CreateFileForMapping(_T("MYTEST.txt"),GENERIC_READ | GENERIC_WRITE,0,NULL,
                                          OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
        ASSERT(hFile != 0);

        DWORD dwLenFile = GetFileSize(hFile,NULL);

        //创建内存文件对象
        HANDLE hMapFile = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,dwLenFile,L"MyMappingFile");
        ASSERT(hMapFile != 0);
       
        //获取内存映射文件对象视图
        LPSTR pData = (LPSTR)MapViewOfFile(hMapFile,FILE_MAP_WRITE,0,0,dwLenFile);
        ASSERT(pData != NULL);

        //*****操作*****
       
        char *pReadBuf = new char[dwLenFile+1];
        strcpy(pReadBuf,pData);
       
        pReadBuf[0] = '5';
        pReadBuf[1] = '2';
        pReadBuf[2] = '0';

        strcpy(pData,pReadBuf);
        //*****关闭*****
        //取消视图
        UnmapViewOfFile(pData);

        //关闭映射文件
        CloseHandle(hMapFile);
       
        //关闭文件
        CloseHandle(hFile);
        delete[] pReadBuf;
 
 
 

回复

91

帖子

0

TA的资源

一粒金砂(初级)

10
 
KevinCEC(我要做人大代表(★★★★))   的方法对于小文件没有问题,但是对于大文件,HANDLE hMapFile = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,dwLenFile,L"MyMappingFile");创建出来的 hMapFile 的值为0。dwLenFile的值太大了。

To mqmmx(魂之结界):
我查了一下,说wince的默认页大小为4 * 1024 * 1024,我设置这个值是能成功的,可是实际文件的大小比这大多了,超过这个长度的 后面的内容怎么去读取呢?
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

11
 
看一下下面的代码

long lout = 1024 << 1000; //定义文件长度256k
//新建文件得到文件指针
IntPtr hFile = File.Create("abc").SafeFileHandle.DangerousGetHandle();
//创建内存文件对象
IntPtr hMap = CreateFileMapping(hFile, IntPtr.Zero, myEnumProtect.PAGE_READWRITE, 0, (int)lout,null);


//每页大小一般为64KB
SYSTEM_INFO sinf = new SYSTEM_INFO();
GetSystemInfo(ref sinf);
int dwAllocationGranularity = sinf.dwAllocationGranularity;

//dwFileOffsetHigh和dwFileOffsetLow组成的64位值来指定
//而且必须是操作系统的分配粒度的整数倍,对于Windows操作系统,分配粒度固定为64KB
IntPtr baseaddr = MapViewOfFile(hMap, myenumFileMap.FILE_MAP_READ | myenumFileMap.FILE_MAP_WRITE, 0, dwAllocationGranularity * 2, 100);

byte[] tmp = new byte[100];
//从128k开始得100个byte
Marshal.Copy(baseaddr,tmp,0, 100);

for (int i = 10; i < 100; i++)
     tmp = (byte)(i + 10);

//将这100byte写回从128k开始的内容
Marshal.Copy(tmp,0,baseaddr, 100);

//关闭文件
UnmapViewOfFile(baseaddr);
CloseHandle(hMap);
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

12
 
没试wince,dwFileOffsetHigh和dwFileOffsetLow应是一个long长度的内容,
应dwFileOffsetHigh = long>>32 ,  dwFileOffsetLow = long & 0x7FFFFFFF的值,你再看看吧
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

13
 
http://www.splife.com/s/Info.aspx?id=93
 
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

14
 
哦,这样啊,那么这个东西,你要优化处理,比如说先读取一部分,然后再读取一部分.

一般对于大文件的处理,只能分段处理. 内存映射的话,处理起来速度上快一些.
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

15
 
非常感谢大家的回复。
最后的结果是:不要求读那么大的文件了。
另外根据这几天的经验,在模拟器上和真实设备上的区别也是挺大的。还有就是内存的分配设置也有影响。

揭帖。谢谢大家了。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表