首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

MapViewOfFile 映射大文件偏移的有关问题

2013-04-02 
MapViewOfFile 映射大文件偏移的问题RT,我需要映射读取一个大文件,几G ~ 十几G文件,这样需要每次一个视图

MapViewOfFile 映射大文件偏移的问题
RT,我需要映射读取一个大文件,几G ~ 十几G文件,这样需要每次一个视图的去映射,但是函数MapViewOfFile 的文件偏移需要系统粒度的最小倍数(一般是64KB),但我的文件结构不是按这个数量对齐,我需要映射每一节,但每节数据长度是不定的,都是保存在节头里面的。
现请教下大家:
1.这种情况下该如何去循环映射读取? 
2.32位系统下一个视图能最大映射多大的文件?


[解决办法]
4G地址空间 
但一半被内核占用(通常情况) 所以最大是2G
其实2G也没有 你不可能只为映射文件留下空间。

个人看法。
[解决办法]
32位程序 默认2G进程空间,即使通过编译控制也就能用到3G,肯定需要有换入换出的
每次映射的大小和你的数据有关,太小可能存在一次无法全部映射进来,太大换入换出太频繁。一直在用这个,我都是按4M进行映射的,每次映射较多,映射次数相对少点  
[解决办法]
楼主为什么不摒弃MapViewOfFile使用_lseeki64呢?
参考下面:

#include <sys\stat.h>
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAX_CLU_BYTES 65536
FILE *fo;
int fh;
__int64 offs,offs1;
__int64 rvi64;
int rv,wrv;
unsigned char buf[MAX_CLU_BYTES];
char ofn[_MAX_PATH];
char offstr[80];
void strcpybutcomma(char *t,char *s) {
    char c;

    while (1) {
        c = *s++;
        if (','!=c) *t++ = c;
        if (0==c) break;
    }
}
void main(int argc,char **argv) {
    if (argc<3) {
        printf("Copy File Tail.\n");
        printf("Usage:\n");
        printf("    cft filename.ext offset_begin[-offset_end]\n");
        printf("Copy filename.ext offset_begin[-offset_end] to offset_begin[-offset_end]-filename.ext\n");
        printf("Note: Byte at offset_end is NOT included.\n");
        printf("Example:\n");
        printf("    cft abc.rar 12345\n");
        printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");
        printf("    cft abc.rar 123-12345\n");
        printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");
        printf("    cft abc.rar 0xAB-0xCD\n");
        printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");
        return;
    }
    strcpybutcomma(offstr,argv[2]);
    rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);
    if (rv==0) {
        printf("offset %s is not number\n",argv[2]);
        return;
    }
    fh=_sopen(argv[1],_O_BINARY


[解决办法]
_O_RDONLY
[解决办法]
_O_RANDOM,_SH_DENYWR);
    if (fh==-1) {
        printf("_sopen %s errno=%d\n",argv[1],errno);
        return;
    }
    if (rv==1) {
        offs1=_filelengthi64(fh);
        if (offs1==-1i64) {
            printf("%I64=_filelengthi64 errno=%d\n",offs1,errno);
            _close(fh);
            return;
        }
    } else {//rv==2
        if (offs1<offs) {
            printf("%s offset_begin>offset_end error\n",argv[2]);
            _close(fh);
            return;
        }
    }
    rvi64=_lseeki64(fh,offs,SEEK_SET);
    if (rvi64!=offs) {
        printf("%I64u=_lseeki64 %I64u errno=%d\n",rvi64,offs,errno);
        _close(fh);
        return;
    }
    sprintf(ofn,"%s-",offstr);
    strcat(ofn,argv[1]);
    fo=fopen(ofn,"wb");
    if (fo==NULL) {
        _close(fh);
        printf("fopen %s error\n",ofn);
        return;
    }
    cprintf("\n%I64u\r",offs);
    while (1) {
        rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));
        if (rv==0) break;//
        if (rv<0) {
            fclose(fo);
            _close(fh);
            printf("_read %s offset %I64u error\n",argv[1],offs);
            return;
        }
        wrv=fwrite(buf,1,rv,fo);
        if (wrv!=rv) {
            fclose(fo);
            _close(fh);
            printf("fwrite %s error\n",ofn);
            return;
        } else {
            offs+=rv;
            cprintf("%I64u\r",offs);


            if (offs>=offs1) break;//
        }
    }
    fclose(fo);
    _close(fh);
    printf("Copy %s offset %s to %s OK.\n",argv[1],argv[2],ofn);
}


[解决办法]
引用:
引用:32位程序 默认2G进程空间,即使通过编译控制也就能用到3G,肯定需要有换入换出的
每次映射的大小和你的数据有关,太小可能存在一次无法全部映射进来,太大换入换出太频繁。一直在用这个,我都是按4M进行映射的,每次映射较多,映射次数相对少点

谢谢楼上朋友,解决思路有了。
你每次只映射4M,这是不太小了点?

映射4M 保存在内存里 ,需要新的再映射,内存不够了清理最近不用的出去
[解决办法]
内存池 + 小块数据映射
[解决办法]
引用:
引用:引用:引用:32位程序 默认2G进程空间,即使通过编译控制也就能用到3G,肯定需要有换入换出的
每次映射的大小和你的数据有关,太小可能存在一次无法全部映射进来,太大换入换出太频繁。一直在用这个,我都是按4M进行映射的,每次映射较多,映射次数相对少点

谢谢楼上朋友,解决思路有……

可以啊,如果这块不会再被用就unmap回去吧
[解决办法]
引用:
引用:引用:引用:引用:引用:32位程序 默认2G进程空间,即使通过编译控制也就能用到3G,肯定需要有换入换出的
每次映射的大小和你的数据有关,太小可能存在一次无法全部映射进来,太大换入换……

肯定有考虑啊  不考虑这东西哪敢用啊
[解决办法]
引用:
引用:引用:引用:引用:引用:引用:引用:32位程序 默认2G进程空间,即使通过编译控制也就能用到3G,肯定需要有换……

有预留  不过也就32bit考虑 64bit基本上不考虑这个
[解决办法]
引用:
引用:楼主为什么不摒弃MapViewOfFile使用_lseeki64呢?
参考下面:C/C++ code?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606……

不要小觑操作系统文件读写Cache功能的效率。
不妨写一个测试程序,实际运行并计时,看看MapViewOfFile到底能比_lseeki64快多少。
[解决办法]
引用:
引用:引用:引用:引用:引用:引用:引用:引用:引用 2 楼 sduxiaoxian……

预留多少程序运行可配置  
预留的肯定不会去释放的

热点排行