一.原理

    通过使用“内存映射文件”,实现内存共享

二.主要操作

    共享内存结构:

  PShareMem = ^TShareMem;
TShareMem = Record
id:string[10];
name:string[20];
age:Integer;
end; // 一定要注意 固定长度

    基本变量:

    shareMemName:string; //共享内存名
fileHandle : THandle;//内存映射文件句柄
pUserInfoShareMem : PShareMem;//指向共享内存的指针

    a)写入程序

1)创建“内存映射文件”

begin
//创建“内存映射文件”
fileHandle:=CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TShareMem), PChar(shareMemName));
if fileHandle <> 0 then
begin
Self.Memo1.Lines.Add('已成功创建内存映射文件!');
end;
end;

2)建立映射关系

  //将“内存映射文件”与“应用程序地址空间”建立映射关系
pUserInfoShareMem:=MapViewOfFile(fileHandle,FILE_MAP_ALL_ACCESS,0,0,sizeof(TShareMem));
if pUserInfoShareMem <> nil then
begin
Self.Memo1.Lines.Add('已成功建立映射关系!');
end;

3)写入信息

   pUserInfoShareMem.id:='8888';
pUserInfoShareMem.name:='Terry';
pUserInfoShareMem.age:=25;
Self.Memo1.Lines.Add('已向共享内存中写入用户信息!');

4)解除映射关系

  //解除“内存映射文件”与“应用程序地址空间”的映射关系
if pUserInfoShareMem<> nil then
UnmapViewOfFile(pUserInfoShareMem);
Self.Memo1.Lines.Add('已成功解除映射关系!');

5)关闭“内存映射文件”

  //关闭内存映射文件
if fileHandle<> 0 then
CloseHandle(fileHandle);
Self.Memo1.Lines.Add('已成功关闭内存映射文件!');

 

    b)读取程序

1)打开“内存映射文件”

 fileHandle:=OpenFileMapping(FILE_MAP_ALL_ACCESS,false,pchar(shareMemName));
if self.FileHandle <> 0 then
begin
Self.Memo1.Lines.Add('已成功打开内存映射文件!')
end;

2)建立映射关系

   pUserInfoShareMem:= MapViewOfFile(self.FileHandle,windows.FILE_MAP_ALL_ACCESS,0,0,sizeof(TShareMem));
if pUserInfoShareMem <> nil then
begin
Self.Memo1.Lines.Add('已成功建立映射关系!');
end;

3)读取信息

   if pUserInfoShareMem <> nil then
begin
userInfoStr:='共享内存中获取的用户信息如下:'+#13#10;
userInfoStr:=userInfoStr+'用户Id号:'+pUserInfoShareMem.id+#13#10;
userInfoStr:=userInfoStr+'用户姓名:'+pUserInfoShareMem.name+#13#10;
userInfoStr:=userInfoStr+'用户年龄:'+IntToStr(pUserInfoShareMem.age);
Self.Memo1.Lines.Add(userInfoStr);
end;

4)解除映射关系

  if pUserInfoShareMem<> nil then
UnmapViewOfFile(pUserInfoShareMem);
Self.Memo1.Lines.Add('已成功解除映射关系!');

5)关闭“内存映射文件”

  if fileHandle<> 0 then
CloseHandle(fileHandle);
Self.Memo1.Lines.Add('已成功关闭内存映射文件!');

====================================================

以下 转自 http://blog.csdn.net/bdmh/article/details/6369250

procedure TGetDataThread.DoGetData;
var
FFile_Handle: THandle;
FFile_Map: THandle;
list: TStringList;
p: PChar;
i, interval: Integer; begin
try
totallen := ;
offset := ;
tstream := TMemoryStream.Create;
stream := TMemoryStream.Create;
list := TStringList.Create;
// 获取系统信息
GetSystemInfo(sysinfo);
// 页面分配粒度大小
blocksize := sysinfo.dwAllocationGranularity;
// 打开文件
FFile_Handle := CreateFile(PChar(FSourceFileName), GENERIC_READ,
FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, );
if FFile_Handle = INVALID_HANDLE_VALUE then
Exit;
// 获取文件尺寸
filesize := GetFileSize(FFile_Handle, nil);
// 创建映射
FFile_Map := CreateFileMapping(FFile_Handle, nil, PAGE_READONLY, , , nil);
if FFile_Map = then
Exit;
// 此处我们已10倍blocksize为一个数据块来映射,如果文件尺寸小于10倍blocksize,则直接映射整个文件长度
if filesize div blocksize > then
readlen := * blocksize
else
readlen := filesize;
for i := to FInfoList.Count - do
begin
list.Delimiter := ':';
list.DelimitedText := FInfoList.Strings[i];
// 取得长度,我这里做了解析,因为我存储的信息为 a:b:c 这种类型,所以以:号分隔
len := StrToInt(list.Strings[]);
interval := StrToInt(list.Strings[]);
if (i = ) or (totallen + len >= readlen) then
begin
// 如果已读取的长度加上即将要读取的长度大于 10倍blocksize,那么我们要保留之前映射末尾的内容,以便和新映射的内容合并
if i > then
begin
offset := offset + readlen;
// 写入临时流
tstream.Write(p^, readlen - totallen);
tstream.Position := ;
end;
// 如果未读取的数据长度已经不够一个分配粒度,那么就直接映射剩下的长度
if filesize - offset < blocksize then
readlen := filesize - offset;
// 映射,p是指向映射区域的指针
// 注意这里第三个参数,一直设为0,这个值要根据实际情况设置
p := PChar(MapViewOfFile(FFile_Map, FILE_MAP_READ, , offset, readlen));
end;
// 如果临时流中有数据,需要合并
if tstream.Size > then
begin
// 把临时流数据copy过来
stream.CopyFrom(tstream, tstream.Size);
// 然后在末尾写入新数据,合并完成
stream.Write(p^, len - tstream.Size);
totallen := len - tstream.Size;
// 移动指针的位置,指向下一个数据的开始
Inc(p, len - tstream.Size);
tstream.Clear;
end
else
begin
stream.Write(p^, len);
totallen := totallen + len;
Inc(p, len);
end;
stream.Position := ;
// 将流保存成文件
stream.SaveToFile(IntToStr(i) + '.txt');
stream.Clear;
end;
finally
stream.Free;
tstream.Free;
CloseHandle(FFile_Handle);
CloseHandle(FFile_Map);
end;
end;

delphi内存映射 与 映射数据获取的更多相关文章

  1. delphi 内存映射

    使用内存映射文件读写大文件 使用内存映射文件读写大文件 文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类.一般来说,这些函数可以满足大多数场合的要求,但是 ...

  2. Delphi内存操作API函数(备查,并一一学习)

    Delphi内存操作API函数System.IsMemoryManagerSet;System.Move;System.New;System.ReallocMem;System.ReallocMemo ...

  3. Delphi 内存与指针

    源:Delphi 内存与指针 Delphi 的内存操作函数(1): 给字符指针分配内存 Delphi 的内存操作函数(2): 给数组指针分配内存 Delphi 的内存操作函数(3): 给结构体指针分配 ...

  4. Delphi 内存分配 StrAlloc New(转)

    源:Delphi 内存分配 StrAlloc New 引自:http://anony3721.blog.163.com/blog/static/5119742010824934164/   给字符指针 ...

  5. 【学习笔记】Hibernate 一对一关联映射 组件映射 二级缓存 集合缓存

    啊讲道理放假这十天不到啊 感觉生活中充满了绝望 这就又开学了 好吧好吧继续学习笔记?还是什么的 一对一关联映射 这次我们仍然准备了两个表 一个是用户表Users 一个是档案表Resume 他们的关系是 ...

  6. JPA(六):映射关联关系------映射单向一对多的关联关系

    映射单向一对多的关联关系 新建项目项目请参考<JPA(二):HellWord工程>,基于上一章讲解的<JPA(五):映射关联关系------映射单向多对一的关联关系>中的例子进 ...

  7. 关于Delphi内存表的使用说明

    关于Delphi内存表的使用说明: 1.建立临时表  数据输入是开发数据库程序的必然环节.在Client/Server结构中,客户端可能要输入一批数据后,再向服务器的后台数据库提交,这就需要在本地(客 ...

  8. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  9. linux I/O 内存分配和映射

    I/O 内存区必须在使用前分配. 分配内存区的接口是( 在 <linux/ioport.h> 定义): struct resource *request_mem_region(unsign ...

随机推荐

  1. Spring Boot 揭秘与实战(二) 数据存储篇 - JPA整合

    文章目录 1. 环境依赖 2. 数据源 3. 脚本初始化 4. JPA 整合方案一 通过继承 JpaRepository 接口 4.1. 实体对象 4.2. DAO相关 4.3. Service相关 ...

  2. DG增量恢复

    本篇文档: 讲述DG环境出现GAP归档缝隙,且主库的该归档日志被删除的情况下,快速恢复DG的连通性 流程讲述: >明确主库增量备份起点 scn 查询备库控制文件current scn ,及v$d ...

  3. MATLAB的一些小经验,记下来,facilitate future work

    [转载请注明出处]http://www.cnblogs.com/mashiqi 2016/03/28 0.杂.这个帖子(https://www.zhihu.com/question/24499729) ...

  4. dp——poj1088(Description)

    dp可以按照思想大致分为两种,一种是递推的形式,一种是递归的形式(记忆化搜素). 比如求这个题因为无法知道从哪个点开始,所以只能用递归的形式,因为有一个回溯的过程. 但是很多题目既可以用递推也可以用递 ...

  5. LOJ 6277:数列分块入门 1(分块入门)

    #6277. 数列分块入门 1 内存限制:256 MiB时间限制:100 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计讨论 3 测试数据 题目描述 给出一 ...

  6. 获奖感想和JAVA阶段性学习总结

    一.获奖感想 事实上,这次能够获得小黄衫,实在是出乎我的意料.毕竟班级中还有不少比我优秀的人,但我不会妄自菲薄.我知道,这件小黄衫不仅仅是老师对我的奖励,更是对我的一种鞭策,一种激励.它要求我要在以后 ...

  7. Go Example--接口

    package main import ( "math" "fmt" ) type geometry interface { area() float64 pe ...

  8. [原] Android上使用native IO

    首先, 官方google play对APK大小有限制: 50M.( https://support.google.com/googleplay/android-developer/answer/113 ...

  9. 从MySQL和MongoDB的对比,看SQL与NoSQL的较量

    张家江,网易乐得高级工程师. 贵金属(注:贵金属为笔者部门业务)的行情系统提供的接口通过Redis获取数据,目前使用Redis最多只存储了大概8000条左右的分钟k的行情数据,考虑到将来可能会有更大数 ...

  10. Truthy and Falsy Values and Equality Operators

    最近在学习JS.  有一些概念还希望跟大家分享出来 Truthy and Falsy Values Falsy Values: undefined, null, 0, '', NaN(not a nu ...