在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一.原理 通过使用“内存映射文件”,实现内存共享 二.主要操作 共享内存结构: 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));
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 := 0; offset := 0; 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, 0); if FFile_Handle = INVALID_HANDLE_VALUE then Exit; // 获取文件尺寸 filesize := GetFileSize(FFile_Handle, nil); // 创建映射 FFile_Map := CreateFileMapping(FFile_Handle, nil, PAGE_READONLY, 0, 0, nil); if FFile_Map = 0 then Exit; // 此处我们已10倍blocksize为一个数据块来映射,如果文件尺寸小于10倍blocksize,则直接映射整个文件长度 if filesize div blocksize > 10 then readlen := 10 * blocksize else readlen := filesize; for i := 0 to FInfoList.Count - 1 do begin list.Delimiter := ':'; list.DelimitedText := FInfoList.Strings[i]; // 取得长度,我这里做了解析,因为我存储的信息为 a:b:c 这种类型,所以以:号分隔 len := StrToInt(list.Strings[1]); interval := StrToInt(list.Strings[2]); if (i = 0) or (totallen + len >= readlen) then begin // 如果已读取的长度加上即将要读取的长度大于 10倍blocksize,那么我们要保留之前映射末尾的内容,以便和新映射的内容合并 if i > 0 then begin offset := offset + readlen; // 写入临时流 tstream.Write(p^, readlen - totallen); tstream.Position := 0; end; // 如果未读取的数据长度已经不够一个分配粒度,那么就直接映射剩下的长度 if filesize - offset < blocksize then readlen := filesize - offset; // 映射,p是指向映射区域的指针 // 注意这里第三个参数,一直设为0,这个值要根据实际情况设置 p := PChar(MapViewOfFile(FFile_Map, FILE_MAP_READ, 0, offset, readlen)); end; // 如果临时流中有数据,需要合并 if tstream.Size > 0 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 := 0; // 将流保存成文件 stream.SaveToFile(IntToStr(i) + '.txt'); stream.Clear; end; finally stream.Free; tstream.Free; CloseHandle(FFile_Handle); CloseHandle(FFile_Map); end; end;
一.原理 通过使用“内存映射文件”,实现内存共享 二.主要操作 共享内存结构: 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));
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 := 0; offset := 0; 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, 0); if FFile_Handle = INVALID_HANDLE_VALUE then Exit; // 获取文件尺寸 filesize := GetFileSize(FFile_Handle, nil); // 创建映射 FFile_Map := CreateFileMapping(FFile_Handle, nil, PAGE_READONLY, 0, 0, nil); if FFile_Map = 0 then Exit; // 此处我们已10倍blocksize为一个数据块来映射,如果文件尺寸小于10倍blocksize,则直接映射整个文件长度 if filesize div blocksize > 10 then readlen := 10 * blocksize else readlen := filesize; for i := 0 to FInfoList.Count - 1 do begin list.Delimiter := ':'; list.DelimitedText := FInfoList.Strings[i]; // 取得长度,我这里做了解析,因为我存储的信息为 a:b:c 这种类型,所以以:号分隔 len := StrToInt(list.Strings[1]); interval := StrToInt(list.Strings[2]); if (i = 0) or (totallen + len >= readlen) then begin // 如果已读取的长度加上即将要读取的长度大于 10倍blocksize,那么我们要保留之前映射末尾的内容,以便和新映射的内容合并 if i > 0 then begin offset := offset + readlen; // 写入临时流 tstream.Write(p^, readlen - totallen); tstream.Position := 0; end; // 如果未读取的数据长度已经不够一个分配粒度,那么就直接映射剩下的长度 if filesize - offset < blocksize then readlen := filesize - offset; // 映射,p是指向映射区域的指针 // 注意这里第三个参数,一直设为0,这个值要根据实际情况设置 p := PChar(MapViewOfFile(FFile_Map, FILE_MAP_READ, 0, offset, readlen)); end; // 如果临时流中有数据,需要合并 if tstream.Size > 0 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 := 0; // 将流保存成文件 stream.SaveToFile(IntToStr(i) + '.txt'); stream.Clear; end; finally stream.Free; tstream.Free; CloseHandle(FFile_Handle); CloseHandle(FFile_Map); end; end;
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论