StartPos:Int64;
MapSize:Cardinal;
function MakeInt64(high,low:Cardinal):int64;
begin
move(pchar(@high)^,pchar(longint(@result)+sizeof(cardinal))^,sizeof(cardinal));
move(pchar(@low)^,pchar(@result)^,sizeof(cardinal));
end;
function High32(num:int64):Cardinal;
begin
move(pchar(longint(@num)+sizeof(cardinal))^,pchar(@result)^,sizeof(cardinal));
end;
function Low32(num:int64):Cardinal;
begin
move(pchar(@num)^,pchar(@result)^,sizeof(cardinal));
end;
begin
PS:=TempPointer;
Inc(PS,32);
PD:=@FileName;
move(PS^,PD^,Rev.Len);
FN:=FileName;
//得到文件长度
size:=Rev.F1;
//得到总文件数
FFileTotalCount:=Rev.F4;
//得到文件类型
fileType:=Rev.F5;
//根据文件类型保存至指定目录下
if fileType=0 then
begin
FH1:=FileCreate(MainForm.FDBFilePath+FileName);
FileClose(FH1);
FH1:=FileOpen(MainForm.FDBFilePath+FileName,fmOpenreadWrite);
end
else
begin
FH1:=FileCreate(MainForm.FMediaFilePath+FileName);
FileClose(FH1);
FH1:=FileOpen(MainForm.FMediaFilePath+FileName,fmOpenreadWrite);
end;
//文件小于1G
if (size/(1024*1024*1024)<1) then
begin
FH2:=CreateFileMapping(FH1,nil,Page_ReadWrite,0,size,nil);
CloseHandle(FH1);
FileMapPointer:=MapViewOfFile(FH2,File_Map_All_Access,0,0,size);
end
else
begin
TotalSize:=size;
//创建内存映射对象
//目标文件
TargetHandle:=FileCreate(MainForm.FMediaFilePath+FileName);
FH2:=CreateFileMapping(FH1,nil,FILE_MAP_READ,HighSize,TotalSize,nil);
tMapHandle:=CreateFileMapping(TargetHandle,nil,PAGE_READWRITE,HighSize,TotalSize,nil);
CloseHandle(TargetHandle);
MainForm.mmo_Report.Lines.Add('☆开始接收文件:'+FileName+',长度'+inttostr(TotalSize div (1024*1024))+'MB,'+TimetoStr(Now()));
//初始化变量
StartPos:=0;
//MapSize:=BufferSize;
MapSize:=Rev.MD;
{ while StartPos<TotalSize do
begin
if StartPos+BufferSize>TotalSize then
MapSize:=TotalSize-StartPos; }
// PSource:=MapViewOfFile(FH2,FILE_MAP_READ,High32(StartPos),Low32(StartPos),MapSize);
PTarget:=MapViewOfFile(tMapHandle,FILE_MAP_READ or FILE_MAP_WRITE, High32(StartPos),Low32(StartPos),MapSize);
StartPos:=StartPos+MapSize;
//复制
move(PByte(FileMapPointer)^,PByte(PTarget)^,MapSize);
{//取消内存映射视图
UnMapViewOfFile(FileMapPointer);
UnMapViewOfFile(PTarget); }
inc(MainForm.FRecCount);
{end; }
//关闭文件映射
//CloseHandle(MH);
//CloseHandle(tMapHandle);
if StartPos = TotalSize then
begin
//取消内存映射视图
UnMapViewOfFile(FileMapPointer);
UnMapViewOfFile(PTarget);
CloseHandle(FH2);
CloseHandle(tMapHandle);
end;
end;
FileSize:=size;//
//文件大小显示
if (FileSize < 1024) then
MainForm.mmo_Report.Lines.Add('☆开始接收文件:'+FileName+',长度'+inttostr(FileSize )+'字节,'+TimetoStr(Now()))
else if (FileSize > 1024) and (FileSize < (1024*1024)) then
MainForm.mmo_Report.Lines.Add('☆开始接收文件:'+FileName+',长度'+inttostr(FileSize div 1024)+'KB,'+TimetoStr(Now()));
{else if (FileSize > (1024*1024)) then
MainForm.mmo_Report.Lines.Add('☆开始接收文件:'+FileName+',长度'+inttostr(FileSize div (1024*1024))+'MB,'+TimetoStr(Now())); }
Echo(1);
end;
发送端文件分段映射如下
///////// 大于1g文件分块传输
FH:=FileOpen(F_MediaUpdateFile[FSendMediaCount].sPath+F_MediaUpdateFile [FSendMediaCount].sFile,fmOpenRead);
if (F_FileSize / (1024*1024*1024)>1) then
begin
//创建内存映射对象
FSize:=GetFileSize(FH,@HighSize);
TotalSize:=HighSize*1024*1024*1024*4+FSize;
MH:=CreateFileMapping(FH,nil,PAGE_READONLY,HighSize,FSize,nil);
//初始化变量
StartPos:=0;
MapSize:=BufferSize;
while StartPos<TotalSize do
begin
if StartPos+BufferSize>TotalSize then
MapSize:=TotalSize-StartPos;
//创建映射视图,获得的PSource和PTarget指针,可以和操作普通指针一样进行内存操作
PSource:=MapViewOfFile(MH,FILE_MAP_READ,High32(StartPos),Low32(StartPos),MapSize);
I := MapSize div J;
K:=MapSize-I*J;
For H:=0 to J-1 do
begin
IF H=J-1 then
I:=I+K;//最后的数据块
SocketThread[H]:= TSocketThread.Create(self,H,H*I,I,PSource);
Event[H] := CreateEvent(nil,False,False,nil);
end;
StartPos:=StartPos+MapSize;
//取消内存映射视图
UnMapViewOfFile(PSource);
//UnMapViewOfFile(PTarget);
end;
//关闭文件映射
CloseHandle(MH);
//CloseHandle(tMapHandle);
这个函数没有你想象的这么简单,你应该再仔细的看看帮助
首先你连每个参数是做什么的都没有弄清楚
第4个参数不能随便设的,FileSize div 5更是不行的
dwFileOffsetLow
Specifies the low-order 32 bits of the file offset where mapping is to begin. The combination of the high and low offsets must specify an offset within the file that matches the system's memory allocation granularity, or the function fails. That is, the offset must be a multiple of the allocation granularity. Use the
GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure, to obtain the system's memory allocation granularity.
supertitan002,你好,查了下MapViewOfFile函数的参数,第四个参数为要映射的字节数。用零映射整个文件映射对象 ,那如果现在分块的话是不是这么写就这么写就可以了,假设分5块:
MP:=MapViewOfFile(MH,File_Map_Read,0,FileSize div 5,FileSize);