文件映射操作类的实现
生活随笔
收集整理的這篇文章主要介紹了
文件映射操作类的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 文件映射操作類的實現
1 文件映射操作類的實現
mmap_file_op.h:
#ifndef QINIU_LARGEFILE_MMAPFILE_OP_H_ #define QINIU_LARGEFILE_MMAPFILE_OP_H_#include "common.h" #include "file_op.h" #include "mmap_file.h"namespace qiniu {namespace largefile{class MMapFileOperation: public FileOperation{public:MMapFileOperation(const std::string& file_name, const int open_flags = O_CREAT | O_RDWR | O_LARGEFILE):FileOperation(file_name, open_flags), map_file_(NULL), is_mapped_(false){}~MMapFileOperation(){if(map_file_){delete(map_file_);map_file_ = NULL;}}int mmap_file(const MMapOption& mmap_option);int munmap_file();int pread_file(char *buf, const int32_t size, const int64_t offset);int pwrite_file(const char* buf, const int32_t sized, const int64_t offset);void *get_map_data() const ;int flush_file();private:MMapFile *map_file_;bool is_mapped_;};} }#endif //QINIU_LARGEFILE_MMAPFILE_OP_H_mmap_file_op.cpp:
#include "mmap_file_op.h" #include "common.h" //#include "file_op.h" //#include "mmap_file.h"static int debug = 1;namespace qiniu {namespace largefile{int MMapFileOperation::mmap_file(const MMapOption& mmap_option){if(mmap_option.max_mmap_size_ < mmap_option.first_mmap_size_){return TFS_ERROR;}if(mmap_option.max_mmap_size_ <= 0){return TFS_ERROR;}int fd = check_file();if(fd < 0){fprintf(stderr, "MMapFileOperation::mmap_file - checking file failed!");return TFS_ERROR;}if(!is_mapped_){if(map_file_){delete(map_file_);}map_file_ = new MMapFile(mmap_option, fd);is_mapped_ = map_file_->map_file(true);}if(is_mapped_){return TFS_SUCCESS;}else {return TFS_ERROR;}}int MMapFileOperation::munmap_file(){if(is_mapped_ && map_file_ != NULL){delete(map_file_);is_mapped_ = false;}return TFS_SUCCESS;}void *MMapFileOperation::get_map_data() const {if(is_mapped_){return map_file_->get_data();}return NULL;}int MMapFileOperation::pread_file(char *buf, const int32_t size, const int64_t offset){//情況1,內存已經映射if(is_mapped_ && (offset + size) >map_file_->get_size()){if(debug) fprintf(stdout, "MMapFileOperation: pread,size: %d, offset: %" __PRI64_PREFIX "d,map file size: %d. need remap\n",size, offset, map_file_->get_size());map_file_->remap_file();}if(is_mapped_ && (offset + size) <=map_file_->get_size()){memcpy(buf, (char *)map_file_->get_data() +offset, size);return TFS_SUCCESS;}//情況2,內存沒有映射或是要讀取的數據映射不全return FileOperation::pread_file(buf, size, offset);}int MMapFileOperation::pwrite_file(const char* buf, const int32_t size, const int64_t offset){//情況1,內存已經映射if(is_mapped_ && (offset + size) >map_file_->get_size()){if(debug) fprintf(stdout, "MMapFileOperation: pwrite,size: %d, offset: %" __PRI64_PREFIX "d,map file size: %d. need remap\n",size, offset, map_file_->get_size());map_file_->remap_file();}if(is_mapped_ && (offset + size) <=map_file_->get_size()){memcpy((char *)map_file_->get_data() +offset, buf, size);return TFS_SUCCESS;}//情況2,內存沒有映射或是要寫入的數據映射不全return FileOperation::pwrite_file(buf, size, offset);}int MMapFileOperation::flush_file(){if(is_mapped_){if(map_file_->sync_file()){return TFS_SUCCESS;}else {return TFS_ERROR;}}return FileOperation::flush_file();}} }test.cpp:
#include "mmap_file_op.h" #include <iostream>using namespace std; using namespace qiniu;const static largefile::MMapOption mmap_option={10240000, 4096, 4096}; //內存映射的參數int main(void) {int ret = 0;const char * filename = "mmap_file_op.txt";largefile::MMapFileOperation *mmfo = new largefile::MMapFileOperation(filename);int fd = mmfo->open_file();if(fd < 0){fprintf(stderr, "open file %s failed. reason: %s\n", filename, strerror(-fd));exit(-1);}ret = mmfo->mmap_file(mmap_option);if(ret == largefile::TFS_ERROR){fprintf(stderr, "mmap_file failed. reason: %s\n", strerror(errno));mmfo->close_file();exit(-2);}char buffer[128+1];memset(buffer, '6', 128);buffer[127]='\n';ret = mmfo->pwrite_file(buffer, 128, 8);if(ret < 0){if(ret == largefile::EXIT_DISK_OPER_INCOMPLETE){fprintf(stderr, " pwrite_file: read length is less than required!\n");}else {fprintf(stderr, "pwrite file %s failed. reason: %s\n", filename, strerror(-ret));}}memset(buffer, 0, 128);ret = mmfo->pread_file(buffer, 128, 8);if(ret < 0){if(ret == largefile::EXIT_DISK_OPER_INCOMPLETE){fprintf(stderr, " pread_file: read length is less than required!");}else {fprintf(stderr, "pread file %s failed. reason: %s\n", filename, strerror(-ret));}}else {buffer[128] = '\0';printf("read: %s\n", buffer);}ret = mmfo->flush_file();if(ret == largefile::TFS_ERROR){fprintf(stderr, "flush file failed. reason: %s\n", strerror(errno));}memset(buffer, '8', 128);buffer[127]='\n';ret = mmfo->pwrite_file(buffer, 128, 4000); // 即使這里的偏移量很大,也會自動擴充文件的mmfo->munmap_file();mmfo->close_file();return 0; }參考資料:
總結
以上是生活随笔為你收集整理的文件映射操作类的实现的全部內容,希望文章能夠幫你解決所遇到的問題。