windows對檔案的讀寫提供了很豐富的操作手段,如:
1. file
*fp, fstearm; (c/c
++)2. cfile, cstdiofile; (mfc)
3. createfile, readfile;(api)
在處理一般的檔案(文字
/非文字),這些足夠了。然而在處理比較大的檔案如
幾十m, 幾百m, 甚至上g的檔案, 這時再用一般手段處理,系統就顯的力不從心了
要把檔案讀出,再寫進,耗費的是cpu利用率與記憶體以及io的頻繁操作。這顯然是
令使用者難以忍受的
為了解決這個吃記憶體,佔cpu,以及io瓶頸,windows核心程式設計提供了記憶體對映檔案技術
(maping file)
至於maping file是什麼原理,我不多說了,網上**資源一籮筐,我只想從應用層
來考慮,怎樣用這個技術,實現日常專案中的應用
舉例來說:
可能專案中,會經常用到一些大量的常量,而這些大量常量用巨集來替**再原始檔中
顯然不可取,一般是寫在檔案中,給常量一些編號,通過編號來索引
一般檔案比較小時候,常用做法也是先預讀到記憶體中,畢竟從記憶體中讀比從檔案中讀要快(io操作的瓶頸)
比較好的做法,讀到stl map 中去:
例如乙個索引檔案:
seu07201213
=汪洋中的一片葉子
jiangsheng=蔣晟
seu07201214
=csdn
開啟檔案,解析
=號,在解析方面有cstring操作,strtok,strstr, boost 正規表示式匹配等等,但我比較喜歡
sscanf(szindex,
"%[^=]=%[^=]
", sname, svalue);
sscanf(szindex,
"%[^=]=%s
", sname, svalue);
fscanf(stream,
"%[^=]=%[^=]
", sname, svalue);
之類,然後再定義乙個map:
map<
string
, string
>
m_map;
m_map[sname]
=svalue;
但是檔案比較大的時候,筆者做過測試,用上面方法處理乙個15m, 25萬行的文字檔案,占用記憶體非常
的高,達70多m,處理的速度也非常的慢,這還不包括回寫到檔案
這時,maping file就派上用場了,這裡處理大檔案就拋棄了map的應用(因為容器占用很多記憶體)
而是直接利用字元指標來操作,不用其他封裝,不多說了,請看示例:
#pragma
warning(disable: 4786)
#include
<
windows.h
>
#include
<
stdio.h
>
#include
<
iostream
>
#include
<
string
>
using
namespace
std;
string
getvalue(
const
tchar *,
const
tchar
*);
//根據name得value
void
main(
intargc,
char
*argv)
//建立檔案對映物件
handle hfilemap =0
, 0, null);
if(hfilemap
==null)
//得到系統分配粒度
system_info sysinfo;
getsysteminfo(
&sysinfo);
dword dwgran
=sysinfo.dwallocationgranularity;
//得到檔案尺寸
dword dwfilesizehigh;
__int64 qwfilesize
=getfilesize(hfile,
&dwfilesizehigh);
qwfilesize
|=(((__int64)dwfilesizehigh)
<<
32);
//關閉檔案物件
closehandle(hfile);
//偏移位址
__int64 qwfileoffset =0
;//塊大小dword dwblockbytes
=1000
*dwgran;
if(qwfilesize
<
1000
*dwgran)
dwblockbytes
=(dword)qwfilesize;
if(qwfileoffset
>=0)
//-----------------------訪問資料開始-------------------------
cout
<<
getvalue(lpbmapaddress,
"seu07201213")
<<
endl;
getchar();
//-----------------------訪問資料結束-------------------------
//撤銷檔案映像
unmapviewoffile(lpbmapaddress);}//
關閉檔案對映物件控制代碼
closehandle(hfilemap);
}string
getvalue(
const
tchar
*lpbmapaddress,
const
tchar
*sname)
return
svalue;
}以上實現了根據索引name匹配value的簡單過程,經測試,同樣25w行檔案,匹配耗費1秒不到,且
不占本程序記憶體。
以上修改lpbmapaddress任意處值,也不需要重新回寫到檔案,真正是大大提高了檔案讀與寫的效率
c語言學習筆記 記憶體管理 linux的記憶體映像
程式在記憶體中的儲存形式 程式儲存在flash中 程式在記憶體中主要分為以下幾段 段,資料段,唯讀資料段,bss段,堆,棧,檔案對映區,核心對映區 作業系統核心 程式一般存放在 段,在linux中又稱為文字段 資料段存放的一般是靜態變數和被初始化為非零值的全域性變數 bss段存放的是被初始化為零的全...
Python讀取大檔案的 坑「與記憶體占用檢測
python讀寫檔案的api都很簡單,一不留神就容易踩 坑 筆者記錄一次踩坑歷程,並且給了一些總結,希望到大家在使用python的過程之中,能夠避免一些可能產生隱患的 隨手搜尋python讀寫檔案的教程,很經常看到read 與readlines 這對函式。所以我們會常常看到如下 with open ...
TCP協議傳輸大檔案讀取時候的問題
大檔案傳不完的bug 我們在定義的時候定義服務端每次檔案讀取大小為10240,客戶端每次接受大小為10240 我們想當然的認為客戶端每次讀取大小就是10240而把客戶端的讀下來的檔案想當然大小每一次都加上10240 而實際上服務端傳送檔案send每次傳送不一定是一次性把10240的檔案傳送完,可能分...