1# 文件映射 2## 概述 3 4文件映射功能。c_utils提供基于文件(file-backed)的内存映射。其将文件映射至进程的地址空间中,从而支持通过文件映射后的地址对文件进行读写操作。 5文件映射能够节省时间以及空间开销。此外,文件映射也可以支持跨进程的信息共享。 6 7## 涉及功能 8 9```mermaid 10classDiagram 11 12class MappedFile{ 13 - String path_ 14 - size_t offset_ 15 - size_t size_ 16 - MapMode mode_ 17 - int mapProt_ 18 - int mapFlag_ 19 - int openFlag_ 20 - const char* hint_ 21 - char* data_ 22 - bool isMapped_ 23 - bool isNormed_ 24 + MappedFile(std::string, size_t, off_t, MapMode, const char*) 25 + MappedFile(MappedFile&& other) noexcept 26 + MappedFile(const MappedFile& other) 27 + MappedFile& operator=(const MappedFile&) 28 + MappedFile& operator=(MappedFile&&) noexcept 29 + inline std::string& GetPath() 30 + inline const char* GetHint() 31 + inline MapMode GetMode() 32 + inline void ChangeSize(size_t size) 33 + inline void ChangeOffset(size_t offset) 34 + inline void ChangePath(string path) 35 + inline void ChangeMode(MapMode mode) 36 + inline void ChangeHint(const char* hint) 37 + ErrCode MapFile() 38 + ErrCode UnMapFile() 39 + ErrCode Resize() 40 + ErrCode Resize(size_t newSize, bool sync) 41 + ErrCode TurnNext() 42 + inline char* Begin() 43 + inline char* End() 44 + inline size_t Size() 45 + inline size_t StartOffset() 46 + inline size_t EndOffset() 47 + inline size_t PageSize() 48 + inline bool IsMapped() 49 + inline bool IsNormed() 50 - ErrCode NormSize() 51 - ErrCode NormMode() 52 - ErrCode SyncFileSize(size_t newSize) 53} 54 55class MapMode { 56 <<Enum>> 57 DEFAULT 58 SHARED 59 PRIVATE 60 READ_ONLY 61 READ_WRITE 62 CREAT_IF_ABSENT 63} 64 65``` 66### OHOS::Utils::MapMode 67#### 描述 68```cpp 69enum class OHOS::Utils::MapMode; 70``` 71映射模式枚举类,包含一系列枚举值以指定文件的映射模式。 72 73#### 枚举值 74|名称 | 值 | 描述 | 75| ---------- | ----- | ----------- | 76| DEFAULT | 0| 默认模式。等价于SHARED|READ_WRITE | 77| PRIVATE | 2| 私有映射模式。对映射区域的写操作不会同步至文件中 | 78| SHARED | DEFAULT| 共享映射模式。对映射区域的写操作会同步至文件中 | 79| READ_ONLY | 4| 只读映射模式。该模式下若对映射区域进行写操作会导致进程退出 | 80| READ_WRITE | DEFAULT| 读写映射模式。该模式下支持对映射区域的读写操作 | 81| CREATE_IF_ABSENT | 8| 创建模式。当指定路径文件不存在时将创建文件后再进行映射 | 82 83### OHOS::Utils::MappedFile 84 85#### 描述 86```cpp 87class OHOS::Utils::MappedFile; 88``` 89文件映射封装类,其用于管理一个文件的映射。 90 91`#include <mapped_file.h>` 92 93#### 公共静态常量 94| | 名称 | 95| -------------- | -------------- | 96| constexpr off_t | **DEFAULT_LENGTH** <br>默认的映射区域大小。 | 97 98#### 公共成员函数 99| 返回类型 | 名称 | 100| -------------- | -------------- | 101| | **MappedFile**(const MappedFile & other) =delete<br>拷贝构造函数。禁止调用,不推荐单一进程内多个映射文件对象对同一段地址进行操作, 可能导致内存泄漏、内存非法访问等问题。 | 102| | **MappedFile**(MappedFile && other) | 103| | **MappedFile**(std::string & path, MappedMode mode =MapMode::DEFAULT, off_t offset =0, off_t size =DEFAULT_LENGTH, const char * hint =nullptr)<br>构造函数。至少需要显式指定待映射的文件路径。 | 104| virtual | **~MappedFile**() | 105| char * | **Begin**() const<br>获取映射后的映射区域首地址。 | 106| bool | **ChangeHint**(const char * hint)<br>指定被映射文件区域的大小 | 107| bool | **ChangeMode**(MappedMode mode)<br>指定被映射文件区域的大小 | 108| bool | **ChangeOffset**(off_t offset)<br>指定被映射文件区域的偏移量。 | 109| bool | **ChangePath**(const std::string & path)<br>指定被映射文件对应路径。 | 110| bool | **ChangeSize**(off_t size)<br>指定被映射文件区域的大小。 | 111| ErrCode | **Clear**(bool force =false)<br>清除映射。解除映射区域,重置所有映射状态及参数,关闭已打开文件。 | 112| char * | **End**() const<br>获取映射后的映射区域尾地址。 | 113| off_t | **EndOffset**() const<br>获取当前指定映射区域尾地址对应的文件偏移量。 | 114| int | **GetFd**() const<br>获取当前指定文件对应的文件描述符 | 115| const char * | **GetHint**() const<br>获取当前指定的映射区域期望首地址 | 116| MappedMode | **GetMode**() const<br>获取当前指定的文件映射模式 | 117| const std::string & | **GetPath**() const<br>获取当前指定的文件路径 | 118| bool | **IsMapped**() const<br>指示是否为已映射状态。 | 119| bool | **IsNormed**() const<br>指示当前参数是否已标准化。 | 120| ErrCode | **Map**()<br>使用当前参数映射文件至内存。参数将被标准化。 | 121| ErrCode | **Normalize**()<br>标准化指定映射参数。 | 122| MappedFile & | **operator=**(const MappedFile & other) =delete<br>拷贝赋值重载函数。禁止调用,不推荐单一进程内多个映射文件对象对同一段地址进行操作, 可能导致内存泄漏、内存非法访问等问题。 | 123| MappedFile & | **operator=**(MappedFile && other) | 124| char * | **RegionEnd**() const<br>获取映射后的映射区域所在页的尾地址。 | 125| char * | **RegionStart**() const<br>获取映射后的映射区域所在页的首地址。 | 126| ErrCode | **Resize**()<br>按照当前参数重新进行映射。 | 127| ErrCode | **Resize**(off_t newSize, bool sync =false)<br>调整映射区域大小,同时保持起始地址不变。可选择同步调整文件大小。 | 128| off_t | **Size**() const<br>获取当前指定的映射区域大小。 | 129| off_t | **StartOffset**() const<br>获取当前指定映射区域首地址对应的文件偏移量。 | 130| ErrCode | **TurnNext**()<br>“翻页”。将当前参数对应的文件中的被映射区域向后平移。注意“翻页”中的“页”并不代表 内存页。 | 131| ErrCode | **Unmap**()<br>解映射当前已映射文件。建议在参数已标准化时调用该方法,避免内存问题。 | 132| off_t | **PageSize**()<br>获取当前内存页大小。 | 133 134## 使用示例 135 1361. 使用方法(伪代码) 137 138```c++ 139 // 1. 创建文件 140 std::string filename = "test_read_write_1.txt"; 141 std::string content = "Test for normal use."; 142 filename.insert(0, SUITE_PATH).insert(0, BASE_PATH); 143 RemoveTestFile(filename); 144 145 CreateTestFile(filename, content); // 该方法创建filename指定的文件并写入content 146 147 // 2. 构造MappedFile对象并进行映射 148 MappedFile mf(filename); 149 mf.Map(); 150 151 // 3. 映射后可通过Begin()方法获取起始地址,并从中读取数据 152 std::string readout; 153 for (char* cur = mf.Begin(); cur <= mf.End(); cur++) { 154 readout.push_back(*cur); 155 } 156 157 // 4. 同样也可以向对应地址中写入数据 158 std::string toWrite("Complete."); 159 char* newCur = mf.Begin(); 160 for (std::string::size_type i = 0; i < toWrite.length(); i++) { 161 (*newCur) = toWrite[i]; 162 newCur++; 163 } 164 std::string res; 165 LoadStringFromFile(filename, res); // res的内容应与toWrite覆盖后的原本内容一致 166 167 // 5. 注意,当试图向End()指示的地址以外(但是不超过该地址一个内存页)写入时,写入不会越界但是写入内容一定不会回写至原文件中。 168 char* trueEnd = mf.RegionEnd(); // RegionEnd() 返回End()指示地址所在的内存页末尾。 169 ASSERT_GT(trueEnd, mf.Begin()); 170 171 (*trueEnd) = 'E'; // 可以向trueEnd指向地址写入数据 172 173 EXPECT_EQ((*trueEnd), 'E'); // 同样也可以读出 174 175 std::string res1; 176 LoadStringFromFile(filename, res1);// 但是文件中不会同步结果, res1仍将和res内容相同。 177 178 // 6. MappedFile对象会在析构时自动解除映射,并关闭内部创建的fd。当然也可以手动解除映射。 179 mf.Unmap(); 180 181 RemoveTestFile(filename); // 该方法删除了创建的文件 182``` 183 1842. 测试用例编译运行方法 185 186- 测试用例代码参见 base/test/unittest/common/utils_mapped_file_test.cpp 187 188- 使用开发者自测试框架,使用方法参见:[开发自测试执行框架-测试用例执行](https://gitee.com/openharmony/testfwk_developer_test#%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E6%89%A7%E8%A1%8C) 189 190- 使用以下具体命令以运行`mapped_file.h`对应测试用例 191 192```bash 193run -t UT -tp utils -ts UtilsMappedFileTest 194``` 195