c++实现读写文件

本程序主要利用mmap函数利用映射的方式实现文件的读写,可以在此基础上改动实现read,write方式

CFile.h

#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <cstring>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>

class CFile
{
public:
	CFile(const std::string& filename);
    virtual ~CFile();

	bool openFile(const char* filemode);
    int getFd() { return fd;}
	int getFileSize();
	bool writeFile(const std::string& data);
	void closeFile();
	bool unlinkFile();
	std::string getFileName(){ return filename;}
	bool checkFile();
	bool reName(const std::string& newname);	
	void readFile(void* buf, int size, int offset);
	void* getMapPtr() { return mapptr;}
	void syncFile(int size) {msync((char*)mapptr+mapsize-size, size, MS_ASYNC);}
	int getFileCreatTime();
private:	
   	bool unmapFile()
	{
		if(mapptr)
		{
			if(munmap(mapptr, maxsize) !=0)
			{
				return false;
			}			
		}
		return true;
    }
	bool mmapFile()
	{
		mapptr = mmap(0, maxsize, PROT_READ|PROT_WRITE, MAP_SHARED,fd, 0);
		if(mapptr == NULL)
		{std::cout<< "map file err\n"; return false;}
		return true;
    }
	off_t getPosition()
	{
		return lseek(fd, 0, SEEK_END);
	}
private:
	int fd;
	FILE* file;
	void* mapptr;
	unsigned long int offset;
	size_t mapsize, maxsize;
	const std::string filename;
    CFile(const CFile&);
	CFile& operator=(const CFile&);
};

CFile::CFile(const std::string& filename):filename(filename),mapsize(0),maxsize(65535),file(NULL)
{}
CFile::~CFile()
{
	if(file)
		closeFile();
}

void CFile::closeFile()
{
	if(fd <0) return;
	if (!unmapFile()) {
		std::cout << "unmap err\n";
	}   
    if(fd >0) close(fd);
	fd = -1;  
	file = NULL;
}

bool CFile::openFile(const char* filemode) //"at+"
{
	if(!checkFile())
	{
		std::cout << "file not exists\n";
		return false;
	}
	file = fopen(filename.c_str(), filemode);
	if(file == NULL)
	{
		std::cout << "open file err\n";
		return false;
	}
	else
	{
		fd = fileno(file);
		mapsize = getPosition();
	}
	return true; 
}

int CFile::getFileSize()
{
	struct stat filestat;
	fstat(fd, &filestat);
	return filestat.st_size;
	// long int curpos,length;
	// curpos = ftell(file);
	// fseek(file, 0L,SEEK_END);
	// length = ftell(file);
	// fseek(file,curpos, SEEK_SET);
	// return length;
}

bool CFile::writeFile(const std::string& data)
{
	size_t datasize = data.size();
	int fileLen = mapsize;
	int offset = datasize + fileLen;
	if(offset >= maxsize)
	{
	    closeFile();
		reName(filename+std::string(".bk"));
		if(!checkFile())
			return false;
	}
	if(fd < 0)
	{	std::cout<< "no open the file\n"; return false;}
	if(ftruncate(fd, offset) < 0)
	{
		return false;
	}		

	mmapFile();
	char *ptr = reinterpret_cast<char*>(mapptr);
	memcpy(ptr+fileLen, data.c_str(), datasize);
	mapsize = offset;
	return true;  
}

bool CFile::unlinkFile()
{
	if(!checkFile())
	{
		return false;
	}
	closeFile();
	return remove(filename.c_str())==0?true:false;
}

bool CFile::checkFile()
{
	if(access(filename.c_str(), F_OK)==0)
		return true;
	else
	{
		int fd = open(filename.c_str(), O_CREAT);
		if(fd < 0)
		{
			std::cout << "create file err\n";
			return false;
		}
		close(fd);
	}
	return true;
}

bool CFile::reName(const std::string& newname)
{
	if(rename(filename.c_str(), newname.c_str())==0)
		return true;
	else
		return false;
}

void CFile::readFile(void* buf, int size, int offs)
{
	if(!checkFile())
	{
		std::cout << "read file err\n";
		return;
	}
	int length = getFileSize();
	if( offs > length)
	{
		std::cout << "offset number too big\n";
		return;
	}
	else
	{
		int readavail = 0;
	    if(size + offs > length)
		{
            readavail = length - offs;		
		}
		else
			readavail = size;
		void* ptr = mmap(NULL, readavail, PROT_READ | PROT_WRITE, MAP_SHARED,  
                         fd, 0);
		char *p = reinterpret_cast<char*>(ptr);		
		memcpy(buf, (void*)(p+offs), readavail);
	}
}

int CFile::getFileCreatTime()
{
	struct stat info;
	stat(filename.c_str(), &info);
	return info.st_ctime;
}

Test.cpp

#include "CFile.h"
int main(int argc, char *argv[])
{
    std::string filename("./log");
	CFile *cFile = new CFile(filename);
	// cFile->openFile("a+");
	// char buf[20] = {'\0'};
	// cFile->readFile(buf, 10, 3);
	// std::cout <<buf <<"\n";
	// cFile->closeFile();
	cFile->openFile("at+");
	std::string writestr("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
	cFile->writeFile(writestr);
	std::string writestr2("sdgagagaergrefzrew\n");
	cFile->writeFile(writestr2);
	cFile->syncFile(writestr.size() + writestr2.size());
	// std::cout << cFile->getFileSize() << "\n";
	cFile->closeFile();
	//const std::string newname("./clog");
	//cFile->reName(newname);
	//cFile->unlinkFile();

    return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值