麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > Delphi > 正文

Delphi 中內(nèi)存映射對(duì)于大文件的使用

2020-01-31 20:50:18
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

Delphi 中內(nèi)存映射對(duì)于大文件的使用

平時(shí)很少使用大文件的內(nèi)存映射,碰巧遇到了這樣的要求,所以把過(guò)程記錄下來(lái),當(dāng)給各位一個(gè)引子吧,因?yàn)閼?yīng)用不算復(fù)雜,可能有考慮不到的地方,歡迎交流。

對(duì)于一些小文件,用普通的文件流就可以很好的解決,可是對(duì)于超大文件,比如2G或者更多,文件流就不行了,所以要使用API的內(nèi)存映射的相關(guān)方法,即使是內(nèi)存映射,也不能一次映射全部文件的大小,所以必須采取分塊映射,每次處理一小部分。

 先來(lái)看幾個(gè)函數(shù)

CreateFile :打開文件

GetFileSize : 獲取文件尺寸

CreateFileMapping :創(chuàng)建映射

MapViewOfFile :映射文件

看MapViewOfFile的幫助,他的最后兩個(gè)參數(shù)都需要是頁(yè)面粒度的整數(shù)倍,一般機(jī)器的頁(yè)面粒度為64k(65536字節(jié)),而我們實(shí)際操作中,一般都不是這樣規(guī)矩的,任意位置,任意長(zhǎng)度都是可能的,所以就要做一些處理。

本例的任務(wù)是從一個(gè)長(zhǎng)度列表中(FInfoList),依次讀取長(zhǎng)度值,然后到另外一個(gè)大文件(FSourceFileName)中去順序讀取指定長(zhǎng)度的數(shù)據(jù),如果是小文件,這個(gè)就好辦了,一次讀到文件流中,然后依次讀取就是了,大數(shù)對(duì)于大文件,就需要不斷改變映射的位置,來(lái)取得我們想要的數(shù)據(jù)。

本例中顯示先通過(guò)GetSystemInfo來(lái)獲取頁(yè)面粒度,然后以10倍的頁(yè)面粒度為一個(gè)映射數(shù)據(jù)塊,在for循環(huán)中,會(huì)判斷已經(jīng)讀取的長(zhǎng)度(totallen)加上即將讀取的長(zhǎng)度,是否在本次映射范圍之內(nèi)(10倍的頁(yè)面粒度),如果在就繼續(xù)讀取,如果超出了,就要記下剩下的數(shù)據(jù),然后重新映射下一塊內(nèi)存,并將記錄下的剩余數(shù)據(jù)合并到新讀取的數(shù)據(jù)中,有點(diǎn)繞?。赡苁俏业南敕ㄌ@了),

下面列出代碼。

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;  //獲取系統(tǒng)信息  GetSystemInfo(sysinfo);  //頁(yè)面分配粒度大小  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);  //創(chuàng)建映射  FFile_Map := CreateFileMapping(FFile_Handle,nil,PAGE_READONLY,0,0,nil);  if FFile_Map = 0 then Exit;  //此處我們已10倍blocksize為一個(gè)數(shù)據(jù)塊來(lái)映射,如果文件尺寸小于10倍blocksize,則直接映射整個(gè)文件長(zhǎng)度  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];   //取得長(zhǎng)度,我這里做了解析,因?yàn)槲掖鎯?chǔ)的信息為 a:b:c 這種類型,所以以:號(hào)分隔   len := StrToInt(list.Strings[1]);   interval := StrToInt(list.Strings[2]);   if (i = 0) or (totallen+len >=readlen) then   begin    //如果已讀取的長(zhǎng)度加上即將要讀取的長(zhǎng)度大于 10倍blocksize,那么我們要保留之前映射末尾的內(nèi)容,以便和新映射的內(nèi)容合并    if i > 0 then    begin     offset := offset + readlen;     //寫入臨時(shí)流     tstream.Write(p^,readlen-totallen);     tstream.Position := 0;    end;    //如果未讀取的數(shù)據(jù)長(zhǎng)度已經(jīng)不夠一個(gè)分配粒度,那么就直接映射剩下的長(zhǎng)度    if filesize-offset < blocksize then     readlen := filesize-offset;    //映射,p是指向映射區(qū)域的指針    //注意這里第三個(gè)參數(shù),一直設(shè)為0,這個(gè)值要根據(jù)實(shí)際情況設(shè)置    p := PChar(MapViewOfFile(FFile_Map,FILE_MAP_READ,0,offset,readlen));   end;   //如果臨時(shí)流中有數(shù)據(jù),需要合并   if tstream.Size > 0 then   begin    //把臨時(shí)流數(shù)據(jù)copy過(guò)來(lái)    stream.CopyFrom(tstream,tstream.Size);    //然后在末尾寫入新數(shù)據(jù),合并完成    stream.Write(p^,len-tstream.Size);    totallen := len-tstream.Size;    //移動(dòng)指針的位置,指向下一個(gè)數(shù)據(jù)的開始    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; 

如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 青青草最新网址 | japan护士性xxxⅹhd | 黄色片视频观看 | 亚洲无线看 | 国产女厕一区二区三区在线视 | 黄色大片免费看 | jizzyouxxxx| 成人免费网站在线观看视频 | 国产69精品久久99不卡免费版 | 国产精品视频六区 | 日本a在线观看 | 中文日韩字幕 | 欧美精品成人一区二区三区四区 | 国产免费看 | 天天碰天天操 | 国产精品一区视频 | 久久国产中文 | 99视频观看 | 成人在线观看免费视频 | 亚洲精品欧美在线 | 欧美性生活久久 | 欧美黑人xx | 麻豆传传媒久久久爱 | 毛片福利 | 毛片免费一区二区三区 | 中文字幕免费一区 | 欧美国产一区二区三区 | 91九色视频观看 | 激情大乳女做爰办公室韩国 | 亚洲成人在线免费观看 | 一本免费视频 | 国产一区二区亚洲 | 国产在线一区二区三区 | 久久久久久久久久久一区 | 最新av在线免费观看 | 欧美日韩亚洲精品一区二区三区 | 国产精品久久久久久久四虎电影 | 操碰在线视频 | 九九精品在线观看视频 | 成人综合一区二区 | 国产精品观看在线亚洲人成网 |