赞
踩
从程序输出的结果来看,你的程序运行的完全正确,就是说,是按照源代码运行的,但你的本意可能并非如此。
你要映射的文件内容是11 22 33 44。 你可能想象运行后应该是22 11 33 44。但按照程序运行下来,结果确实应该是2 3311 2。
解释:
11 22 33 44是键盘输入的吧。文件是用某个文本编辑程序做的吧。计算机里保存的文件是按二进制编码的,文本文件的字符也不例外。在这个文件中,11 22 33 44实际上保存成:
0x31('1') 0x31('1') 0x20(空格符) 0x32('2') 0x32('2') 0x20(空格符) 0x33('3') 0x33('3') 。
。。
但你的程序却要把他们映射成整形数据。 一个整数是四个字节, 因此, 程序把第一组4个字节作为base[0], 第二组4个字节作为base[1], 即:
base[0]=0x32203131, base[1]=0x33332032,。
。。
(注意我们PC机对于整数的四个字节是掉过头来处理的)
swap之后, base[0]=0x33332032, base[1]=0x32203131。 由于是映射, 所以文件也变了。 把他们还原成字节顺序:
0x32('2') 0x20(空格符) 0x33('3') 0x33('3') 0x31('1') 0x31('1') 0x20(空格符) 0x32('2')
就是2 3311 2了。
试试下面的程序:
char x[] = "11 22 33";
int *p = (int *)x;
printf("%d[0xx]", *p, *p);
输出的整数是840970545[0x32203131],一个道理。
要点:
所谓MapVieew, 就是说文件的内容和所映射的内存是一致的。 因此, 内存把整数11表示为0x0000000B, 四个字节顺序为十六进制的0B 00 00 00,
那么文件中那四个字节也是0B 00 00 00才对。
用文本编辑软件手工敲进的整数叫数字字符, 不是整形数据。 你骗计算机说这是整形数据, 当然出不来你预想的结果了。
试验:
你的程序别作任何修改, 你的所谓整形数据文件也不做任何修改, 只需在swap()之前加上一行:
base[0]=22; base[1]=11;
程序结束后当然base[0]=11, base[1]=22了。
但重要的是你的数据文件(前8字节)真正成为你需要的整形数据文件了。 他的前8个字节是:
0B 00 00 00 16 00 00 00 。。。。
如果用文本编辑软件打开, 你绝对看不到"11 22。。
。"。
把刚刚增加的这一行删掉, 恢复原来的样子编译后执行, 会看到11和22互相交换位置了, 可能你原来就预想的这个结果吧。
总结:
使用MapViewOfFile对文件进行映射,如何按整数读取文件的内容?关键在于你建立的文件确实是整型数的文件。
所映射文件的建立一般也是直接把内存内容拷贝到映射区中去。 举例: 整型数组a[N]保存成文件(映射内存指针为p):
memcpy(p,a,sizeof(a));
即可。 当然p必须确切建立, 其长度不小于a的大小。
但是直接操作映射区更能发挥MaView的优势。比如顺序向文件中写入0,100,200,300,400的整数:
。。。。
int *p = (int *)MapViewOfFile(hobj, FILE_MAP_ALL_ACCESS, 。
。。);
for (i=0;i>5; i) p[i]=i*100;
。。。。
就可以了。不需要任何读写文件的语句。
全部
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。