怎样实现分段映射文件到内存(没高手吗,分低可以再加)(100分)

  • 主题发起人 主题发起人 lqcros
  • 开始时间 开始时间
L

lqcros

Unregistered / Unconfirmed
GUEST, unregistred user!
分段读取,分段写入
 
用内存地址映射你要指定的大小段啊,<br>var<br> &nbsp;FFileMode: Integer;<br> &nbsp;ProtectAttr: DWORD;<br> &nbsp;Access: LongInt;<br>begin<br> &nbsp;FFileMode := fmOpenReadWrite;<br> &nbsp;FFileHandle := FileOpen(FSourceFile,FFileMode);<br> &nbsp;if FFileHandle = INVALID_HANDLE_VALUE then<br> &nbsp; &nbsp;raise EMMError.Create('无法打开文件');<br> &nbsp;try<br> &nbsp; &nbsp;FFileSize := GetFileSize(FFileHandle,nil);<br> &nbsp; &nbsp;if FFileSize = 0 then<br> &nbsp; &nbsp; &nbsp;raise EMMError.Create('要打开的文件大小为零');<br><br> &nbsp; &nbsp;if FFileMode = fmOpenRead then<br> &nbsp; &nbsp; &nbsp;ProtectAttr := Page_ReadOnly<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;ProtectAttr := Page_ReadWrite;<br> &nbsp; &nbsp;//创建文件映射对象<br> &nbsp; &nbsp;FMapFileHandle := CreateFileMapping(FFileHandle,nil,ProtectAttr,0,FFileSize,nil);<br> &nbsp; &nbsp;if FMapFileHandle = 0 then<br> &nbsp; &nbsp; &nbsp;raise EMMError.Create('创建文件映射失败');<br> &nbsp;finally<br> &nbsp; &nbsp;CloseHandle(FFileHandle);<br> &nbsp;end;<br> &nbsp;try<br> &nbsp; &nbsp;if FFileMode = fmOpenRead then<br> &nbsp; &nbsp; &nbsp;Access := FILE_MAP_READ<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Access := FILE_MAP_ALL_ACCESS;<br> &nbsp; &nbsp;//建立文件视图映射<br> &nbsp; &nbsp;FMapView := MapViewOfFile(FMapFileHandle,Access,0,0,0); //这可以指定映射大小<br> &nbsp; &nbsp;if FMapView = nil then<br> &nbsp; &nbsp; &nbsp;raise EMMError.Create('将文件映射到进程空间失败');<br> &nbsp;finally<br> &nbsp; &nbsp;CloseHandle(FMapFileHandle);<br> &nbsp;end;<br>end;<br>-------------------------------------<br>内存映射其实就是一个指针,你可以用地址+偏移量的方式获取啊
 
同意楼上的
 
我说的是分段映射哈。<br>如果文件大小大于4G,如10G怎么办
 
其实都是一样的啊,映射函数里面的高位参数最高可以支持160G呢,你看看CreateFileMapping,MapViewOfFile函数的帮助吧,建议楼主看看windows高级编程的书
 
对的,只想映射一小段
 
上面的函数中 DWORD dwMaximumSizeHigh这个参数就是当要映射的文件大于4G时文件大小,<br>MapViewOfFile中dwNumberOfBytesToMap参数就是你要一次映射文件的大小。看看帮助吧
 
分段映射读取我懂了,不过怎么分段映射写入<br>如:<br>我想写入一个数据到文件,<br>文件又比较大<br>我只能分段映射,如何把数据写入呢<br>还有,如果我写入的数据在前一段写不完,只能再映射下一段,写入,又怎么办
 
是写入新文件还是当前文件写啊?如果新文件,就可以再创建一个内存映射文件。FMapView其实就是一个指针地址,可以类似于流的方式进行读写操作,可以用Move等函数进行指针移动,其实你可以把他看成是线型的,用地址+偏移量的方式进行写操作啊
 
写入一个已存在的文件,
 
留个Mail发个写的Demo给你,那是修改文件的例子
 
lqcros@163.com
 
程序已经发了,希望对你有些帮助。
 
jacket84:<br>对于内存映象我可以理解,但你说的<br>&quot;内存映射其实就是一个指针,你可以用地址+偏移量的方式获取啊&quot;<br>如果用地址+偏移量来做呢?<br><br>以前学过汇编,对偏移量知道,但不知在 delphi 中该怎么来用,请多多指教<br><br>谢谢
 
学习一下
 
内存映射文件就是不通过将文件加载到缓存,而通过映射直接定位硬盘上的文件。这时后你可以认为文件内容都在内存中。而定位到的文件第一个字节(或者说文件头)可以得到一个内存地址,也就是指针(如$00BC01),这时候你就可以以这个指针地址为基地址,如果你想取这个地址以后的第5个字节的内容,不就可以以基地址+5个偏移量来操作呢,(内存地址是线性的)。<br>我是这样认为的,如果说得不对,请大家指教。
 
/to:jacket84<br>你发过来的东西收到了,不过不是分段映射的。<br>分段映射 读取,我弄懂了,<br>分段映射 写入,我还没弄懂
 
是想要同时在不同的段写入?还是分先后写入啊?
 
分段先后写入,<br>经如我每一段64K,<br>我要写1M的数据到文件<br>写了64K,马上就要映射下一段,直到写完为止
 
你是新建文件还是对本文件进行操作啊? 我感觉你好像不需要这么做的啊,你既然知道写入的第一个映射的内存地址,你就可以在该地址+你写的数据大小就可以得到新的地址,当然这个前提是你操作的是同一个文件。你能把东西讲的详细些吗
 

Similar threads

回复
0
查看
978
不得闲
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部