對映檔案到記憶體,像操作記憶體一樣方便讀寫檔案——MemFile
阿新 • • 發佈:2019-01-26
編碼中操作檔案是常有的事,本文封裝了一種不一樣的讀寫檔案方式,通過對映檔案可以想操作記憶體一樣方便的讀寫檔案。
方法解釋:
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; } };