能力值:
( LV10,RANK:170 )
|
-
-
2 楼
您这个问题,放了1天多, 也没有人回复。我解答一下吧。
在解答之前,您只需要明白2个原则:
1> 应用程序预定地址空间时,系统会确保区域的起始地址正好是分配粒度的整数倍。
2> 应用程序预定地址空间的一块区域时,系统会确保区域大小为系统页面大小的整数倍
假设现在X86~X64的平台使用的分配粒度为 64KB, 然后X86~X64系统使用的页面大小为4KB。
那么计算一下:某应用程序试图预定一块大小为10KB的地址空间区域,那么X86~X64系统会实际分配12KB
有了上面的概念 就好解释你的问题了。
CreateFileMapping 的 参数4 和参数5 是用来表示大小的. 如果你文件大于32位的描述,也就是4GB,那么第4个参数就有用了。 提示你一下: 高低字节
按照你说的,其实在你系统在32位下,设置第5个参数为多少,一般不会有问题。刚刚测试过。
下面解答你的2个问题
想映射部分(比如8个字节)该如何实现?
答: 按照前面说的思路,分配粒度和页面大小的结合, 先预测你的8个字节 在第几个页面,然后按照分配粒度进行MapViewOfFile 就行了。
文件映射对象的大小有什么作用?
答:这个大小的作用其实就是告诉MapViewOfFile这个API可以最大映射多少个字节到地址空间.
|
能力值:
( LV6,RANK:80 )
|
-
-
3 楼
上传了一个测试txt,用代码测试了你说的32位系统下第五个参数设置为多少一般都可以,这里我设置了
// Create a file-mapping object for the file.
HANDLE hFileMapping = ::CreateFileMapping(hFile,
NULL,
PAGE_WRITECOPY,
0, 4096*2,//4096也是运行崩溃
NULL);
PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0,0, 4096);
导致运行崩溃了,这个跟你说的是否矛盾?
文件映射对象的大小有什么作用?
答:这个大小的作用其实就是告诉MapViewOfFile这个API可以最大映射多少个字节到地址空间. 这里我告诉MapViewOfFile最大可以映射4096个字节,并且在MapViewOfFile中也让他映射了4096个字节,但是实际运行却出现内存错误,这里是不是因为4096个字节不在同一个页面上?
|
能力值:
( LV10,RANK:170 )
|
-
-
4 楼
你的认真阅读,让我有点意外。 针对 “第5个参数的设置”问题,我没有详细表达。
导致你误解,下面我详细化一些
1> CreateFileMapping 中,你使用的是 PAGE_WRITECOPY 标志位,那么这个标志位表明 你可以在你的data.txt大小范围内设置,比如100 。如果超过data.txt大小范围,就出错。
那么没有可以不限制大小范围呢?有使用 PAGE_READWRITE标志位,具体你可以详细查看文档
2>MapViewOfFile,我的解释,你应该没有问题把。 你还做个实验,可以验证我的想法。 比如你在CreateFileMapping中设置大小为100,那么你在MapViewOfFile 设置4096 会发生什么事情。
|
能力值:
( LV6,RANK:80 )
|
-
-
5 楼
HANDLE hFileMapping = ::CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0, 100,
NULL);
PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0,0, 4096);
改成这样,出现上述结果,直接挂了。。。。。
|
能力值:
( LV10,RANK:170 )
|
-
-
6 楼
嗯, 那你明白 了吗?
|
能力值:
( LV6,RANK:80 )
|
-
-
7 楼
CreateFileMapping告诉了最大可以映射到是100,这里映射了4096远远超过了100,就崩溃了,但是我在这里把CreateFileMapping设置成4096,然后MapViewOfFile也设成4096依然崩溃呢.....是我哪里没理解到位呢?
|
能力值:
( LV10,RANK:170 )
|
-
-
8 楼
很抱歉,我这边没有崩溃。 你认真检查一下你的代码~,你也可以选择贴代码~。 不过,我绝对你应该单步跟踪调试,或许并不是 MAPFILE 这组API 出错的。
|
能力值:
( LV6,RANK:80 )
|
-
-
9 楼
#include <windows.h>
#include<tchar.h>
#include <iostream>
#include<stdio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = ::CreateFile("C:\\data.txt",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
HANDLE hFileMapping = ::CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0, 4096,
NULL);
cout<<GetLastError()<<endl;
PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0,0, 4096);
cout<<GetLastError()<<endl;
cout << pbFile << endl;
调试前面都没错,就最后这里错误cout<<pfFile<<endl;
调试发现pbFile ------------0x003b0000
data.txt中第一个字符数=,如果换成cout<<*pbFile<<endl;则输出为=,这里pbFile指针的值应该就没错,但是怎么cout<<pbFile<<endl;就崩溃呢?
|
能力值:
( LV10,RANK:170 )
|
-
-
10 楼
嗯,按照现象,已经解决完你的核心问题了。 剩下基本是 C C++ 指针 和 文件操作问题。
这些东西是很基础了,建议自己解决把。
|
能力值:
( LV6,RANK:80 )
|
-
-
11 楼
你的没问题,是你的data.txt文件比较小吧,用我的data.txt是会出现问题的,我用的data.txt比4k大了一些,出现问题的原因是真的不清楚,不过找到了一些蛛丝马迹,
#include <windows.h>
#include<tchar.h>
#include <iostream>
#include<stdio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile = ::CreateFile("C:\\data.txt",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
cout<<GetLastError()<<endl;
HANDLE hFileMapping = ::CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0, 4096,
NULL);
cout<<GetLastError()<<endl;
PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0,0, 4096);
cout<<GetLastError()<<endl;
[COLOR="Red"]pbFile[4095]='\0';[/COLOR] cout<<pbFile<<endl;
这样就能输出,换成4096就出错,是什么原因导致,莫非是缓冲区的问题?4K的限制?
但是后来又给否定了,
HANDLE hFileMapping = ::CreateFileMapping(hFile,
NULL,
PAGE_READWRITE,
0, 5000,
NULL);
cout<<GetLastError()<<endl;
PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0,0, 5000);
cout<<GetLastError()<<endl;
cout<<pbFile<<endl;
5000不崩溃,4096真的就崩溃了..................我也快崩溃了。。。。。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
占个楼先,一会儿再发表意见
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
这样就能输出,换成4096就出错,是什么原因导致,莫非是缓冲区的问题?4K的限制? 但是后来又给否定了,
....换成4096当然会出错了
数组是从0开始的。4K的数组最大索引是4095...你改成4096不崩才怪呢
|
能力值:
( LV6,RANK:80 )
|
-
-
14 楼
你误会了我的意思吧,这里是不是缓冲区的原因还不确定呢?那5000的时候不写怎么也可以输出?
补充:data.txt 大小:4.13kb 4230字节
4096<4230
5000>4230
应该是跟大小有关的吧。.。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
这两个函数还真没有细细追求过,明天来试试。。。
|
|
|