windows内存映射学习及帮助类实现

本文通过创建文件内存映射类,学习windows内存映射相关知识;创建内存映射文件后,可以按照内存操作方式操作文件

感谢http://blog.csdn.net/csafu/article/details/8602142,

引用部分内容"文件映射问题

内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。

所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,

内存管理的相关知识非常复杂,超出了本文的讨论范畴,在此就不再赘述,感兴趣的读者可以参阅其他相关书籍。

下面给出使用内存映射文件的一般方法:

首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。

在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。

为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉

系统文件的尺寸以及访问文件的方式。在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据

作为映射到该区域的物理存储器进行提交。由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分

映射到进程地址空间。此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,

在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。

这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、

通过CloseHandle()关闭前面创建的文件映射对象和文件对象。"

  1 #ifndef MEMFILEMAPHELPER_H
  2 #define MEMFILEMAPHELPER_H
  3 //文件内存映射类,创建内存映射文件;创建后,可以按照内存操作方式操作文件
  4 /*
  5 文件映射问题
  6 内存映射文件并不是简单的文件I/O操作,实际用到了Windows的核心编程技术--内存管理。
  7 所以,如果想对内存映射文件有更深刻的认识,必须对Windows操作系统的内存管理机制有清楚的认识,
  8 内存管理的相关知识非常复杂,超出了本文的讨论范畴,在此就不再赘述,感兴趣的读者可以参阅其他相关书籍。
  9 下面给出使用内存映射文件的一般方法:
 10
 11 首先要通过CreateFile()函数来创建或打开一个文件内核对象,这个对象标识了磁盘上将要用作内存映射文件的文件。
 12 在用CreateFile()将文件映像在物理存储器的位置通告给操作系统后,只指定了映像文件的路径,映像的长度还没有指定。
 13 为了指定文件映射对象需要多大的物理存储空间还需要通过CreateFileMapping()函数来创建一个文件映射内核对象以告诉
 14 系统文件的尺寸以及访问文件的方式。在创建了文件映射对象后,还必须为文件数据保留一个地址空间区域,并把文件数据
 15 作为映射到该区域的物理存储器进行提交。由MapViewOfFile()函数负责通过系统的管理而将文件映射对象的全部或部分
 16 映射到进程地址空间。此时,对内存映射文件的使用和处理同通常加载到内存中的文件数据的处理方式基本一样,
 17 在完成了对内存映射文件的使用时,还要通过一系列的操作完成对其的清除和使用过资源的释放。
 18 这部分相对比较简单,可以通过UnmapViewOfFile()完成从进程的地址空间撤消文件数据的映像、
 19 通过CloseHandle()关闭前面创建的文件映射对象和文件对象。
 20 */
 21
 22 #include <Windows.h>
 23 #include <WinBase.h>
 24 #include <string>
 25 #include <iostream>
 26 using namespace std;
 27
 28 //typedef unsigned char    byte;
 29 //typedef unsigned long   DWORD;
 30 //typedef void*            HANDLE;
 31
 32 class CMemFileMapHelper{
 33 public:
 34     enum MemFileType{SEQ_READ=0,SEQ_WRITE,RANDOM_READ,RANDOM_WRITE,SEQ_READ_WRITE,RANDOM_READ_WRITE};
 35 protected:
 36     HANDLE m_FileHandler;//原始文件句柄
 37     HANDLE m_FileMemMapHandler;//内存映射文件句柄
 38     unsigned __int64 m_FileSize;
 39     byte* m_BaseAddr;//内存映射文件首地址,m_BaseAddr+n =>访问文件第n字节处的位置
 40     bool m_FileMapped;//是否映射
 41 public:
 42     CMemFileMapHelper(){
 43         m_FileMapped = false;
 44         m_FileHandler = NULL;
 45         m_FileMemMapHandler = NULL;
 46         m_BaseAddr = NULL;
 47         m_FileSize = 0;
 48     }
 49     ~CMemFileMapHelper(){
 50         if(m_FileMapped)
 51             ReleaseFileMapping();
 52     }
 53
 54     void ShowError(char* errmsg){
 55         cout<<errmsg<<endl;
 56     }
 57
 58     //将文件加载到内存映射
 59     bool BuildFileMapping(const char* fileName,MemFileType type = SEQ_READ, unsigned __int64 view_size=0){
 60         DWORD err_code;
 61         char err_msg[100];
 62         string shared_name = GetLastFileName(fileName);
 63
 64         //存取模式//GENERIC_READ | GENERIC_WRITE
 65         DWORD access_mode;
 66
 67         //共享模式// FILE_SHARE_READ | FILE_SHARE_WRITE
 68         DWORD share_mode;
 69
 70         /*文件属性:
 71         FILE_FLAG_WRITE_THROUGH        操作系统不得推迟对文件的写操作
 72         FILE_FLAG_OVERLAPPED        允许对文件进行重叠操作
 73         FILE_FLAG_NO_BUFFERING        禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块
 74         FILE_FLAG_RANDOM_ACCESS        针对随机访问对文件缓冲进行优化
 75         FILE_FLAG_SEQUENTIAL_SCAN        针对连续访问对文件缓冲进行优化
 76         FILE_FLAG_DELETE_ON_CLOSE        关闭了上一次打开的句柄后,将文件删除。特别适合临时文件
 77         */
 78         DWORD mmf_flag;
 79
 80         /*打开文件方式:
 81         CREATE_NEW        创建文件;如文件存在则会出错
 82         CREATE_ALWAYS    创建文件,会改写前一个文件
 83         OPEN_EXISTING    文件必须已经存在。由设备提出要求
 84         OPEN_ALWAYS        如文件不存在则创建它
 85         TRUNCATE_EXISTING        讲现有文件缩短为零长度*/
 86         DWORD file_create_mode;
 87
 88         /*页面内存访问方式:
 89         PAGE_EXECUTE      可执行
 90         PAGE_EXECUTE_READ    可读,可执行
 91         PAGE_EXECUTE_READWRITE 可读,可写,可执行
 92         PAGE_EXECUTE_WRITECOPY 可读,可写,可执行,以Read-on-write和copy-on-write方式共享
 93         PAGE_NOACCESS           不可访问
 94         PAGE_READONLY           只读 并且hFile对应的文件必须以GENERIC_READ形式打开。
 95         PAGE_READWRITE          可读,可写 并且hFile对应的文件必须以GENERIC_READ 和 GENERIC_WRITE形式打开。
 96         PAGE_WRITECOPY          copy-on-write保护机制 并且hFile对应的文件必须以GENERIC_READ 和 GENERIC_WRITE形式打开。
 97         PAGE_GUARD              保护,如果访问则异常(不能单独使用)
 98         PAGE_NOCACHE            不进行CPU缓存(不能单独使用)
 99         PAGE_WRITECOMBINE       write-combined优化(不能单独使用)
100         */
101         DWORD page_access_mode;
102
103         /*虚拟页面视图访问方式
104         FILE_MAP_WRITE:一个可读写属性的文件视图被创建,保护模式为PAGE_READWRITE
105         FILE_MAP_READ :一个只读属性的文件视图被创建,保护模式为PAGE_READWRITE 或 PAGE_READONLY
106         FILE_MAP_ALL_ACCESS:与FILE_MAP_WRITE模式相同
107         FILE_MAP_COPY:保护模式为PAGE_WRITECOPY时,得到一个视图文件,当你对视图文件写操作时,页面自动交换,并且你所做的修改不会损坏原始数据资料。
108         */
109         DWORD view_access;
110
111         //文件映射为一个映像,映像的大小=> size_t view_size
112
113         switch(type){
114         case SEQ_READ:
115             {
116                 access_mode = GENERIC_READ;
117                 share_mode = FILE_SHARE_READ;
118                 mmf_flag = FILE_FLAG_SEQUENTIAL_SCAN;
119                 file_create_mode = OPEN_EXISTING;
120                 page_access_mode = PAGE_READONLY;
121                 view_access = FILE_MAP_READ;
122                 view_size = 0;//将整个文件映射为一个映像
123             }
124             break;
125         case RANDOM_READ:
126             {
127                 access_mode = GENERIC_READ;
128                 share_mode = FILE_SHARE_READ;
129                 mmf_flag = FILE_FLAG_RANDOM_ACCESS;
130                 file_create_mode = OPEN_EXISTING;
131                 page_access_mode = PAGE_READONLY;
132                 view_access = FILE_MAP_READ;
133                 view_size = 0;
134             }
135             break;
136         case SEQ_WRITE:
137             {
138                 access_mode = GENERIC_READ | GENERIC_WRITE;
139                 share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
140                 mmf_flag = FILE_FLAG_WRITE_THROUGH;//FILE_FLAG_SEQUENTIAL_SCAN
141                 file_create_mode = CREATE_NEW;
142                 page_access_mode = PAGE_READWRITE;
143                 view_access = FILE_MAP_WRITE;
144             }
145             break;
146         case RANDOM_WRITE:
147             {
148                 access_mode = GENERIC_READ | GENERIC_WRITE;
149                 share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
150                 mmf_flag = FILE_FLAG_RANDOM_ACCESS;
151                 file_create_mode = CREATE_NEW;
152                 page_access_mode = PAGE_READWRITE;
153                 view_access = FILE_MAP_WRITE;
154             }
155             break;
156         case SEQ_READ_WRITE:
157             {
158                 access_mode = GENERIC_READ | GENERIC_WRITE;
159                 share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
160                 mmf_flag = FILE_FLAG_SEQUENTIAL_SCAN;
161                 file_create_mode = OPEN_ALWAYS;
162                 page_access_mode = PAGE_READWRITE;
163                 view_access = FILE_MAP_READ|FILE_MAP_WRITE;//FILE_MAP_ALL_ACCESS
164             }
165             break;
166         case RANDOM_READ_WRITE:
167             {
168                 access_mode = GENERIC_READ | GENERIC_WRITE;
169                 share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
170                 mmf_flag = FILE_FLAG_RANDOM_ACCESS;
171                 file_create_mode = OPEN_ALWAYS;
172                 page_access_mode = PAGE_READWRITE;
173                 view_access = FILE_MAP_READ|FILE_MAP_WRITE;//FILE_MAP_ALL_ACCESS
174             }
175             break;
176         default:
177             return false;
178         }
179
180         //1.创建文件
181         /*
182         HANDLE CreateFile(
183           LPCTSTR lpFileName, //指向文件名的指针
184            DWORD dwDesiredAccess, //访问模式(写/读)
185             DWORD dwShareMode, //共享模式
186             LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
187             DWORD dwCreationDisposition, //如何创建
188             DWORD dwFlagsAndAttributes, //文件属性
189             HANDLE hTemplateFile //用于复制文件句柄
190         );
191         返回值
192           如执行成功,则返回文件句柄。
193             INVALID_HANDLE_VALUE表示出错,会设置GetLastError。
194             即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS
195         */
196         m_FileHandler = CreateFile(fileName,access_mode,share_mode,NULL,file_create_mode,mmf_flag,NULL);
197         err_code = GetLastError();
198         switch(err_code){
199             case INVALID_HANDLE_VALUE:
200                 sprintf(err_msg,"文件打开失败");
201                 ShowError(err_msg);
202                 return false;
203                 break;
204             case ERROR_ALREADY_EXISTS:
205                 if(m_FileHandler == NULL &&(type == SEQ_WRITE || type == RANDOM_WRITE) ){
206                     sprintf(err_msg,"文件已存在");
207                     ShowError(err_msg);
208                     return false;
209                 }
210                 break;
211         }
212
213         //2.创建文件映射
214         /*
215         HANDLE CreateFileMapping(
216         HANDLE hFile,                       //物理文件句柄
217         LPSECURITY_ATTRIBUTES lpAttributes, //安全设置, 一般NULL
218         DWORD flProtect,                    //保护设置
219         DWORD dwMaximumSizeHigh,            //高位文件大小
220         DWORD dwMaximumSizeLow,             //低位文件大小
221         LPCTSTR lpName                      //共享内存名称
222         );
223
224         调用CreateFileMapping的时候GetLastError的对应错误
225         ERROR_FILE_INVALID     如果企图创建一个零长度的文件映射, 应有此报
226         ERROR_INVALID_HANDLE   如果发现你的命名内存空间和现有的内存映射, 互斥量, 信号量, 临界区同名就麻烦了
227         ERROR_ALREADY_EXISTS   表示内存空间命名已经存在
228         */
229
230         //2.1获取文件大小
231         DWORD fileSizeLow = 0,fileSizeHigh = 0;
232         if(type == SEQ_READ || type == RANDOM_READ || type == SEQ_READ_WRITE || type == RANDOM_READ_WRITE){
233             fileSizeLow = GetFileSize(m_FileHandler,&fileSizeHigh);
234             //文件长度
235             m_FileSize = ((unsigned __int64)fileSizeHigh << 32) + (unsigned __int64)fileSizeLow;
236         }
237         else
238         {
239             m_FileSize = view_size;//待创建的文件的大小
240             fileSizeHigh = view_size >> 32;
241             fileSizeLow = view_size & 0xFFFFFFFF;
242         }
243
244         //2.2创建映射文件
245         m_FileMemMapHandler = CreateFileMapping(m_FileHandler,NULL,page_access_mode,fileSizeHigh,fileSizeLow,shared_name.c_str());
246         err_code = GetLastError();
247         if(m_FileMemMapHandler == NULL){
248             sprintf(err_msg,"创建映射文件错误");
249             CloseHandle(m_FileHandler);
250             ShowError(err_msg);
251             return false;
252         }
253
254         switch(err_code){
255             case ERROR_FILE_INVALID:
256                 {
257                     sprintf(err_msg,"企图创建一个零长度的文件映射错误");
258                     CloseHandle(m_FileHandler);
259                     ShowError(err_msg);
260                     return false;
261                 }
262                 break;
263             case ERROR_INVALID_HANDLE:
264                 {
265                     sprintf(err_msg,"你的命名内存空间和现有的内存映射, 互斥量, 信号量, 临界区同名");
266                     CloseHandle(m_FileHandler);
267                     ShowError(err_msg);
268                     return false;
269                 }
270                 break;
271             case ERROR_ALREADY_EXISTS:
272                 {
273                     sprintf(err_msg,"内存空间命名已经存在");
274                     CloseHandle(m_FileHandler);
275                     ShowError(err_msg);
276                     return false;
277                 }
278                 break;
279         }
280
281         //3.加载映射文件
282         /*
283         LPVOID   MapViewOfFile(
284         HANDLE   hFileMappingObject,   //物理文件句柄
285         DWORD   dwDesiredAccess,       //对文件数据的访问方式
286         DWORD   dwFileOffsetHigh,      //文件的偏移地址高位
287         DWORD   dwFileOffsetLow,       //文件的偏移地址低位
288         DWORD   dwNumberOfBytesToMap);
289
290         文件的偏移地址由DWORD型的参数dwFileOffsetHigh和dwFileOffsetLow组成的64位值来指定,
291         而且必须是操作系统的分配粒度的整数倍,对于Windows操作系统,分配粒度固定为64KB
292
293         dwNumberOfBytesToMap:映射文件部分的大小,如果为0,则映射整个文件。
294         返回值:
295         如果成功返回返回映射视图的起始地址,如果失败返回NULL。
296
297         在完成对映射到进程地址空间区域的文件处理后,需要通过函数UnmapViewOfFile()完成对文件数据映像的释放,该函数原型声明如下:
298         BOOL   UnmapViewOfFile(LPCVOID   lpBaseAddress);
299         */
300
301         //3.1动态获取当前操作系统的分配粒度:
302         /*SYSTEM_INFO   sinf;
303         GetSystemInfo(&sinf);
304         DWORD   dwAllocationGranularity   =   sinf.dwAllocationGranularity;
305         if(type == SEQ_WRITE || type == RANDOM_WRITE){
306         int imod = view_size % dwAllocationGranularity;
307         if(imod != 0)
308         view_size = (1+(view_size / dwAllocationGranularity))*dwAllocationGranularity;
309         }*/
310
311         //3.2把文件数据映射到进程的地址空间
312         m_BaseAddr = (byte*)MapViewOfFile(m_FileMemMapHandler,view_access,0,0,view_size);
313         if(m_BaseAddr != NULL){
314             m_FileMapped = true;
315             return true;
316         }
317         else{
318             sprintf(err_msg,"文件数据映射到进程的地址空间错误");
319             CloseHandle(m_FileMemMapHandler);
320             CloseHandle(m_FileHandler);
321             ShowError(err_msg);
322             return false;
323         }
324     }
325
326     bool ReleaseFileMapping(){
327         /*
328         在完成对映射到进程地址空间区域的文件处理后,需要通过函数UnmapViewOfFile()完成对文件数据映像的释放,该函数原型声明如下:
329         BOOL   UnmapViewOfFile(LPCVOID   lpBaseAddress);   // lpBaseAddress 映射视图起始地址
330         */
331         if(!m_FileMapped || m_BaseAddr == NULL) return false;
332         //1.释放文件数据映像
333         UnmapViewOfFile(m_BaseAddr);
334         //2.关闭内存映射句柄
335         CloseHandle(m_FileMemMapHandler);
336         //3.关闭进行内存映射的文件
337         CloseHandle(m_FileHandler);
338         m_FileMapped = false;
339         m_FileHandler = NULL;
340         m_FileMemMapHandler = NULL;
341         m_BaseAddr = NULL;
342         m_FileSize = 0;
343         return true;
344     }
345     string GetLastFileName(const char* pathName){
346         char spliter = ‘\\‘;
347         int pos = strlen(pathName);
348         for(;pos>=0 &&(*(pathName+pos)) != spliter; pos--);
349         const char* fname = pathName + (pos + 1);
350         string fileName(fname);
351         return fileName;
352     }
353     bool IsFileMapped(){
354         return m_FileMapped;
355     }
356     unsigned __int64 GetCurFileSize(){
357         if(m_FileMapped)
358             return m_FileSize;
359         else
360             return -1;
361     }
362     byte* GetMemFileBaseAddr()const{
363         if(m_FileMapped)
364             return m_BaseAddr;
365         else
366             return NULL;
367     }
368
369     //从相对m_BaseAddr首地址offset位置拷贝len长度的数据到dst;确保dst有足够的内存空间
370     bool GetMemory(void* dst,unsigned __int64 offset, size_t len){
371         if(offset + len > m_FileSize) return false;
372         memcpy(dst,m_BaseAddr+offset,len);
373         return true;
374     }
375     //向相对m_BaseAddr首地址offset位置写入len长度的src数据;确保src有足够的内存空间
376     bool WriteMemory(void* src,unsigned __int64 offset, size_t len){
377         /*在使用内存映射文件时,为了提高速度,系统将文件的数据页面进行高速缓存,
378         而且在处理文件映射视图时不立即更新文件的磁盘映像。
379         为解决这个问题可以考虑使用FlushViewOfFile()函数,
380         该函数强制系统将修改过的数据部分或全部重新写入磁盘映像,
381         从而可以确保所有的数据更新能及时保存到磁盘。
382
383         将内存复制到所映射的物理文件上面
384         FlushMapViewOfFile函数可以将内存里面的内容DUMP到物理磁盘上面
385         FlushViewOfFile 把文件映射视图中的修改的内容或全部写回到磁盘文件中
386         BOOL FlushViewOfFile(
387         LPCVOID lpBaseAddress,       // 修改内容的起始地址
388         DWORD dwNumberOfBytesToFlush // 修改的字节数目
389         );
390         函数执行成功返回非零。
391         */
392         if(offset + len > m_FileSize) return false;
393         memcpy(m_BaseAddr+offset,src,len);
394         FlushViewOfFile(m_BaseAddr+offset,len);//把文件映射视图中的修改的内容或全部写回到磁盘文件中
395         return true;
396     }
397 };
398 #endif

测试:

 1 // Demo.cpp : 定义控制台应用程序的入口点。
 2 //
 3
 4 #include "stdafx.h"
 5 #include <iostream>
 6 #include <fstream>
 7 #include <string>
 8 #include "MemFileMapHelper.h"
 9 using namespace std;
10
11
12 typedef struct{
13     double X;
14     double Y;
15     double Z;
16 }stru_pos;
17
18 int main(int argc, char* argv[])
19 {
20     bool flag;
21     int nSize = 10;
22     char* fileName = "F:\\Code\\cpp\\Demo\\Demo\\test.txt";
23
24     stru_pos *posArr = new stru_pos[nSize];
25     for (int i=0;i<nSize;i++)
26     {
27         posArr[i].X = i+1;
28         posArr[i].Y = i+2;
29         posArr[i].Z = i+3;
30     }
31
32     CMemFileMapHelper fh;
33     //seq write
34     flag = fh.BuildFileMapping(fileName,CMemFileMapHelper::SEQ_WRITE,nSize * sizeof(stru_pos));
35     if(flag){
36         fh.WriteMemory(posArr,0,nSize*sizeof(stru_pos));
37         fh.ReleaseFileMapping();
38     }
39     if(!flag) return -1;
40
41     ////radom write
42     //flag = fh.BuildFileMapping(fileName,CMemFileMapHelper::RANDOM_WRITE,nSize * sizeof(stru_pos));
43     //if(flag){
44     //    for (int i=nSize-1;i>=0 && flag;i--)
45     //    {
46     //        flag = fh.WriteMemory(&posArr[i],i*sizeof(stru_pos),sizeof(stru_pos));
47     //        cout<<posArr[i].X <<" "<<posArr[i].Y <<" "<<posArr[i].Z<<endl;
48     //    }
49     //    fh.ReleaseFileMapping();
50     //}
51     //if(!flag) return -1;
52
53     //seq read
54     flag = fh.BuildFileMapping(fileName,CMemFileMapHelper::SEQ_READ);
55     for (int i=0;i<nSize && flag;i++)
56     {
57         stru_pos pos;
58         flag = fh.GetMemory(&pos,i*sizeof(stru_pos),sizeof(stru_pos));
59         cout<<pos.X <<" "<<pos.Y <<" "<<pos.Z<<endl;
60     }
61     fh.ReleaseFileMapping();
62
63     ////random read
64     //flag = fh.BuildFileMapping(fileName,CMemFileMapHelper::RANDOM_READ);
65     //for (int i=nSize - 1;i>=0 && flag;i--)
66     //{
67     //    stru_pos pos;
68     //    flag = fh.GetMemory(&pos,i*sizeof(stru_pos),sizeof(stru_pos));
69     //    cout<<pos.X <<" "<<pos.Y <<" "<<pos.Z<<endl;
70     //}
71     //fh.ReleaseFileMapping();
72
73     ////random read write
74     //flag = fh.BuildFileMapping(fileName,CMemFileMapHelper::SEQ_READ_WRITE);
75     //stru_pos pos;
76     //flag = fh.GetMemory(&pos,5*sizeof(stru_pos),sizeof(stru_pos));
77     //cout<<pos.X <<" "<<pos.Y <<" "<<pos.Z<<endl;
78     //pos.X = pos.Y = pos.Z = 13;
79     //flag = fh.WriteMemory(&pos,5*sizeof(stru_pos),sizeof(stru_pos));
80     //cout<<pos.X <<" "<<pos.Y <<" "<<pos.Z<<endl;
81     //fh.ReleaseFileMapping();
82
83     delete[] posArr;
84     cin>>flag;
85     return 0;
86 }
时间: 2024-08-13 05:13:35

windows内存映射学习及帮助类实现的相关文章

Windows内存映射文件打造极速复制(速度已和ExtremeCopy商业软件相当)

如题,先贴图,后续上传源码和exe 测试文件大小7.08GB: 结果: 商业软件ExtremeCopy 2.1测试结果: 

C#内存映射文件学习[转]

原文链接 内存映射文件是由一个文件到进程地址空间的映射. C#提供了允许应用程序把文件映射到一个进程的函(MemoryMappedFile.CreateOrOpen).内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存.由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再

Java内存分配(直接内存、堆内存、Unsafel类、内存映射文件)

1.Java直接内存与堆内存-MarchOn 2.Java内存映射文件-MarchOn 3.Java Unsafe的使用-MarchOn 简单总结: 1.内存映射文件 读文件时候一般要两次复制:从磁盘复制到内核空间再复制到用户空间,内存映射文件避免了第二次复制,且内存分配在内核空间,应用程序访问的就是操作系统的内核内存空间,因此极大提高了读取效率.写文件同理. 2.堆内存分配与直接内存分配: Java申请空间时通常是从JVM堆内存分配的,即 ByteBuffer.allocate(int cap

windows 文件内存映射

static int MapLogFile(void) { hFile = CreateFile(".\\db.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL); if (INVALID_HANDLE_VALUE == hFile) { goto err; } hMap = CreateFileMapping(h

.NET Framework自带的文件内存映射类

最近一直为文件内存映射发愁,整个两周一直折腾这个东西.在64位系统和32位系统还要针对内存的高低位进行计算.好麻烦..还是没搞定 偶然从MSDN上发现.NET 4.0把内存文件映射加到了.NET类库中..好像方便了很多啊..比用C#直接调用WINDOWS API方便多了.所以 这个必须果断记录之...项目马上要用,为了加强内存数据交换的效率..这个...必须啊.. 任务 使用的方法或属性 从磁盘上的文件中获取表示持久内存映射文件的 MemoryMappedFile 对象. MemoryMappe

转:C#制作ORM映射学习笔记一 自定义Attribute类

之前在做unity项目时发现只能用odbc连接数据库,感觉非常的麻烦,因为之前做web开发的时候用惯了ORM映射,所以我想在unity中也用一下ORM(虽然我知道出于性能的考虑这样做事不好的,不过自己的小项目吗管他的,自己爽就行了).不过现在世面上的ORM映射基本都是为web项目设计的,与unity项目很难契合,所以我决定自己做一个简易的ORM映射.虽然想的很美但是实际做起来才发现还是挺复杂的,所以我在这里记录一下这次的开发过程,防止以后遗忘. 今天先记录一下如何通过自定义attribute类实

Motherboard Chipsets and the Memory Map.主板芯片组与内存映射

原文标题:Motherboard Chipsets and the Memory Map 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的精彩文章翻译一下.一来自己复习,二来与大家分享.] 我打算写一组讲述计算机内幕的文章,旨在揭示现代操作系统内核的工作原理.我希望这些文章能对电脑爱好者和程序员有所帮助,特别是对这类话题感兴趣但没有相关知识的人们.讨论的焦点是Linux,Windows,和Intel处理器.钻研系统内幕是我的一个

Windows API 编程学习记录&lt;三&gt;

恩,开始写API编程的第三节,其实马上要考试了,但是不把这节写完,心里总感觉不舒服啊.写完赶紧去复习啊       在前两节中,我们介绍了Windows API 编程的一些基本概念和一个最基本API函数 MessageBox的使用,在这节中,我们就来正式编写一个Windows的窗口程序. 在具体编写代码之前,我们必须先要了解一下API 编写窗口程序具体的三个基本步骤:             1. 注册窗口类:             2.创建窗口:             3.显示窗口: 恩,

JAVA NIO 内存映射(转载)

原文地址:http://blog.csdn.net/fcbayernmunchen/article/details/8635427 Java类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原理. 在传统的文件IO操作中,我们都是调用操作系统提供的底层标准IO系统调用函数 read().write() ,此时调用此函数的进程(在JAVA中即java进程)由当