编码中操作文件是常有的事,本文封装了一种不一样的读写文件方式,通过映射文件可以想操作内存一样方便的读写文件。
方法解释:
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;
}
};