c++实现读写文件

原创 2015年11月20日 16:18:57

本程序主要利用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;
}


相关文章推荐

C++读写文件的实现

  • 2012年05月10日 16:10
  • 28KB
  • 下载

C++ 读写文件详解

C++ 读写文件详解 掌握文本文件读写的方法,了解二进制文件的读写方法 C++文件流: fstream  // 文件流 ifstream   // 输入文件流 ofstream  /...

C++ 读写文件

  • 2012年11月27日 17:29
  • 852B
  • 下载

C++ 读写文件

  • 2013年06月05日 12:31
  • 20.34MB
  • 下载

TCPL C++迭代器的用法 用作参数传递 读写文件

C++数据流迭代器(iterators)一般不直接使用,而是用做某些算法的参数。这些算法多是STL中的算法,是用C习惯了的朋友,应该会觉得这个有点不需太习惯,但是这就是C++的方法,据C++之父Bej...

C++读写文件

  • 2014年04月05日 15:02
  • 16KB
  • 下载

c++:学籍管理系统(读写文件)

  • 2011年10月15日 16:26
  • 950KB
  • 下载

C++ fstream读写文件

1. 头文件1.1 fstream#include < fstream > #include std::fstream f; // 要有命名空间1.2 setw()” in...

两种方法实现C#读写文件

  • 2017年02月10日 11:05
  • 998B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++实现读写文件
举报原因:
原因补充:

(最多只允许输入30个字)