文章目录

  • 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;
}

参考资料:

  1. C/C++从入门到精通-高级程序员之路【奇牛学院】

文件映射操作类的实现相关推荐

  1. java文件读写操作类

    借鉴了项目以前的文件写入功能,实现了对文件读写操作的封装 仅仅需要在读写方法传入路径即可(可以是绝对或相对路径) 以后使用时,可以在此基础上改进,比如: 写操作: 1,对java GUI中文本框中的内 ...

  2. 史上最完整的文件和目录操作类

    [文件操作类]史上最完整的文件和目录操作类 <a target=_blank href="http://bbs.cskin.net/thread-114-1-1.html"& ...

  3. java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射

    http://langgufu.iteye.com/blog/2107023 java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果 ...

  4. 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射...

    内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码. file ...

  5. Java学习总结:41(文件操作类:File)

    Java文件操作类:File 在java.io包中,如果要进行文件自身的操作(例如:创建.删除等),只能依靠java.io.File类完成. File类的常用操作方法 No. 方法 类型 描述 1 p ...

  6. 如何在xaml文件中操作用户在后台代码定义的类(1)

    本文主要示例如何在xaml文件中操作用户使用C#代码自定义的类.主要步骤如下: 1.在VS2008中创建一个新项目CustomTypesInXaml,在此项目下我们新建两个类,一个是Client类,一 ...

  7. 黄聪:C# MP3操作类,能播放指定的mp3文件,或播放嵌入的资源中的Mp3文件

    以下为我写的Mp3操作类源代码: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  8. 用MyEclipse自动生成hibernate映射文件和实体类

    创建web工程,使用Hibernate的时候,在工程里一个一个创建实体类太麻烦,浪费时间,现在教大家如何用MyEclipse自动生成Hibernate映射文件及实体类 方法/步骤 1 创建数据库,创建 ...

  9. SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)...

    本文将示例如何运用前篇所写知识来建立一个用户自定义的登录控件.此控件界面非常简单,主要涉及的知识点是:   如何创建用户控件(包括对此控件的自定义事件和属性的编写,此处我们将创建一个名为LoginBo ...

最新文章

  1. Hbase表结构设计
  2. php 实例说明 socket通信机制
  3. 重装MS SQL Server 2000前必须彻底删除原安装文件!
  4. 04 java 基础:数据类型
  5. android真机调试看不到logcat信息
  6. JBPM 3.3.0 + JBOSS 4.2.3 + ORACLE 9i
  7. PL/SQL(一)简介
  8. 【Tensorflow】图像的读取、解码、显示、处理、编码、保存
  9. 服务器Java环境配置
  10. 微信小程序解析php,微信小程序解析H5文件方法
  11. nginx静态代理设置一:静态文件在本机
  12. 洛洛阅读—自己写的简约Android小说阅读器背景
  13. 采用顺序存储实现队列的初始化、入队、出队操作。/验证实验/
  14. 深入理解Java虚拟机(10-13)学习总结
  15. 至少8位密码,包括大写、小写、数字、特殊字符中的三种即可(一般强密码规则)
  16. PTA A1100 Mars Numbers 解题思路
  17. 华为鲲鹏HCIA考试-练习04
  18. TRUNK端口的配置实验
  19. python趣味编程-python趣味入门——写几个常玩的游戏
  20. JHM3000体温传感器驱动

热门文章

  1. mysql 节点查根_(三)B数、B+树及在数据库索引中应用
  2. 【任务脚本】0530更新淘宝618活动领喵币脚本,OrangeJs基于autojs全自动程序稳定运行,向大神致敬...
  3. 安检x光机原理计算机实现,安检x光机成像原理介绍
  4. 数据结构-js实现栈和队列
  5. CSS keylogger:攻击与防御
  6. 学习开发自己的composer包,并使用GitHub实时更新到Packagist
  7. 陌陌联席总裁离职 股价大涨背后阿里收购传闻再起
  8. laravel 中创建全局函数 (类似于 TP 中 functions.php) 的方式
  9. 来自 IsayNo (@IsayNooo) 的推文
  10. IMOAutocompletionViewController