映射文件到内存,像操作内存一样方便读写文件——MemFile

本文介绍了一种独特的文件操作方式,通过类封装实现文件映射,允许用户像操作内存一样方便地读写文件。包括关联、取消关联、创建、清理、匿名映射、重新映射、检查存在性、目录创建、文件删除和获取大小等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编码中操作文件是常有的事,本文封装了一种不一样的读写文件方式,通过映射文件可以想操作内存一样方便的读写文件。

方法解释:

Attach:关联已存在的文件并映射到内存,不存在返回NULL;

Detach:取消关联机器映射;

Alloc:创建一个新的文件并映射到内存;

Calloc:如果已经存在则清空;

Aalloc:匿名映射;

Realloc:已经存在直接映射,不存在则创建一个;

Release:释放,功能同Detach;

Exist:判断是否存在;

Makedir:创建目录,可以多级目录

Delete:删除文件;

Length:求文件大小;

有源码有真相,下面是源代码:

class MemFile
{
public:
    static void* Attach(const char *name)
    {
        size_t filelen = Length(name);
        if(-1 == filelen) return NULL;

        int fd = open(name, O_RDWR);
        if(-1 == fd) return NULL;

        void *addr = mmap(NULL, filelen, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
        close(fd);
        
        if(MAP_FAILED == addr)return NULL;
        
        return addr;
    }
    
    static void Detach(void *addr, size_t length)
    {
        if(addr != NULL && length != -1) munmap(addr, length);
    }
    
    static void* Alloc(const char *name, size_t length)
    {
        int fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0644);
        if(-1 == fd) return NULL;

        if(ftruncate(fd, length) != 0) {close(fd); return NULL;}
        
        void *addr = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
        close(fd);
        
        if(MAP_FAILED == addr)return NULL;
        
        return addr;
    }

    static void* Calloc(const char *name, size_t length)
    {
        int fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
        if(-1 == fd) return NULL;

        if(ftruncate(fd, length) != 0) {close(fd); return NULL;}
        
        void *addr = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
        close(fd);
        
        if(MAP_FAILED == addr)return NULL;
        
        return addr;
    }

    static void* Aalloc(size_t length)
    {
        void *addr = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_ANONYMOUS, -1, 0);
        if(MAP_FAILED == addr)return NULL;
        
        return addr;
    }
    
    static void* Realloc(const char *name, size_t length)
    {
        if(Length(name) == length) return Attach(name);
        else if(Length(name) == -1) return Alloc(name, length);
        else return NULL;
    }

    static void Release(void *addr, size_t length)
    {
        if(addr != NULL && length != -1) munmap(addr, length);
    }
    
    static bool Exist(const char *name)
    {
        if(access(name, F_OK) == 0) return true;

        return false;
    }
    
    static bool Makedir(const char *name)
    {
        size_t len = strlen(name);
        char dir[256] = {0};
        if(len >= sizeof(dir)) return false;
        for(size_t i = 0; i < len; ++i)
        {
            if(name[i] == '/')
            {
                strncpy(dir, name, i+1);

                if(Exist(dir)) continue;
                if(mkdir(dir, 0755) == -1) return false;
            }
        }

        return true;
    }
    
    static void Delete(const char *name)
    {
        remove(name);
    }
    
    static size_t Length(const char *name)
    {
        struct stat statbuff;
        if(stat(name, &statbuff) < 0) return -1;
        
        return statbuff.st_size;
    }
};

 

 

对于大文件读写操作,Qt提供了多种方法,其中一种常用的方法是使用内存映射(Memory Mapping)技术。 内存映射允许将文件的内容映射到进程的地址空间中,从而可以直接通过内存访问文件的内容,而不需要显式地进行读写操作。这种方式可以提高读写效率,并且对于大文件的处理更为高效。 在Qt中,可以使用QFile和QIODevice类提供的内存映射功能来实现大文件读写操作。具体步骤如下: 1. 打开文件:使用QFile类打开要进行内存映射的文件。 ```cpp QFile file("path/to/file"); if (file.open(QIODevice::ReadWrite)) { // 文件打开成功 } ``` 2. 创建内存映射:使用QFile的map()函数创建一个QMemoryMappedFile对象,并将其指定为读写模式或只读模式。 ```cpp QMemoryMappedFile memFile; if (memFile.open()) { if (memFile.map(&file, QMemoryMappedFile::ReadWrite)) { // 内存映射创建成功 } } ``` 3. 获取映射的数据指针:通过QMemoryMappedFile对象的data()函数获取映射的数据指针。 ```cpp char* data = static_cast<char*>(memFile.data()); ``` 4. 进行读写操作:可以直接通过data指针对文件内容进行读写操作,类似于普通的内存操作。 ```cpp // 写入数据 memcpy(data, "Hello, world!", 14); // 读取数据 QString content = QString::fromUtf8(data); ``` 5. 解除内存映射和关闭文件:完成读写操作后,需要解除内存映射并关闭文件。 ```cpp memFile.unmap(); file.close(); ``` 需要注意的是,使用内存映射技术需要谨慎处理文件大小和内存占用,避免因为大文件或者内存限制而导致程序崩溃或性能问题。此外,还需要注意处理文件不存在或者无法打开的异常情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值