こんにちは、克兎です。
記事を書いてる途中で、
ブラウザが停止したけど
何なの?
Webページが応答してませんとか、もう何行書いたと思って…
うわあぁぁあぁぁぁあん!
あれだね、
MicroSoftもたいした事ないね。
はい、
前回の続きでっす~。
メモリマップドファイルでファイル操作を行うには、
3つの関数が必要です。
[1回]
以下、MSDNのコピペ
1,ファイルを開く関数。
HANDLE CreateFile(
LPCTSTR lpFileName, // ファイル名
DWORD dwDesiredAccess, // アクセスモード
DWORD dwShareMode, // 共有モード
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // セキュリティ記述子
DWORD dwCreationDisposition, // 作成方法
DWORD dwFlagsAndAttributes, // ファイル属性
HANDLE hTemplateFile // テンプレートファイルのハンドル
);
2,ファイルをメモリにマッッピングする関数。
HANDLE CreateFileMapping(
HANDLE hFile, // ファイルのハンドル
LPSECURITY_ATTRIBUTES lpAttributes, // セキュリティ
DWORD flProtect, // 保護
DWORD dwMaximumSizeHigh, // サイズを表す上位 DWORD
DWORD dwMaximumSizeLow, // サイズを表す下位 DWORD
LPCTSTR lpName // オブジェクト名
);
3,マッピングオブジェクトを取得する関数。
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // ファイルマッピングオブジェクトのハンドル
DWORD dwDesiredAccess, // アクセスモード
DWORD dwFileOffsetHigh, // オフセットの上位 DWORD
DWORD dwFileOffsetLow, // オフセットの下位 DWORD
SIZE_T dwNumberOfBytesToMap // マップ対象のバイト数
);
これを見てもよく分らないですよね。
俺もわからん。
参考になるホームページはあるけどぶっちゃけ覚える必要はありません。
なので概要は簡単に説明します。
CreateFile関数は、ファイルを開くor作る関数ですね。
開く際のオプション等の設定が可能です。
CreateFileMapping関数は
メモリ上にファイルをマッピングする関数です。
メモリ上にマッピングされたデータを
マッピングオブジェクトと言います。
イメージとしてはインスタンス化に近いですね。
コンストラクタを通らないので厳密には違うんですが…。
MapViewOfFile関数は
作成されたマッピングオブジェクトを取得する関数です。
newやmallocなんかと同じように、
確保されたマッピングオブジェクトはポインタで保持します。
戻り値が
汎用ポインタになっているのはそういうことですね。
この戻り値を
好きな型にキャストしてやることで自由な型ファイルを作ることができます。
このポインタを、
マップビューと言います。
今回、サンプルソースを用意しました。
ファイルに事前に文字列を書きこんでおいて、それを読み込み、コンソールで書き換える。
という内容のものです。
まずは、前準備から。
main.cpp
//変数宣言****************************************************************************
HANDLE hFile; //ファイルのハンドル
HANDLE hMap; //マッピングオブジェクトのハンドル
char* mapView; //マッピングオブジェクトへのポインタ
//ファイルマッピングの流れ*******************************************************************************
//Section1:ファイルを開く
hFile = CreateFile( "data.txt" , GENERIC_READ | GENERIC_WRITE , 0 , 0 , OPEN_ALWAYS , 0 , 0 );
if( hFile == INVALID_HANDLE_VALUE )
{
printf( "ファイルオープン失敗したしー" ); //エラー
return 1;
}
//Section2:メモリ空間上にマッピング
hMap = CreateFileMapping( hFile , 0 , PAGE_READWRITE , 0 , 0 , "FileMapping_katuusagi" );
if( hMap <= 0 )
{
printf( "ファイルをマッピングできねーしー." ); //エラー
CloseHandle( hFile ); //せっかく開いたけどクローズせざるを得ない(´;ω;`)
return 1;
}
//Section3:マッピングしたデータへのポインタを取得
mapView = ( char * )MapViewOfFile( hMap , FILE_MAP_ALL_ACCESS , 0 , 0 , 0 );
if( mapView == NULL )
{
CloseHandle( hMap ); //せっかくマップしたけどクローズせざるを得ない(´;ω;`)
CloseHandle( hFile ); //せっかく開いたけどクローズせざるを得ない(´;ω;`)
printf( "マップビューが取得できねーしー" ) ; //エラー
return 1;
}
|
これは必要最小限の処理群です。
開くべきファイルである"data.txt"の中身が空の場合、
CreateFileMappingでエラーが発生します。
なので、事前に、ルートフォルダに以下のファイルを作成してください。
data.txt
続いて、ファイルの中身を書き換えるところです
main.cpp
//ファイルの操作****************************************************************************************
printf( "書き換える前のファイルの中身:\n%s\n\n" , mapView ); //ファイルの表示
printf( "データを入力してね:" ); //
scanf( "%s" , mapView ); //ここだけでファイルが書き変えられる
printf( "\n\n書き換えた後のファイルの中身:\n%s\n" , mapView ); //ファイルの表示
|
え、こんだけ?
関数の説明は必要ないですよね。
文字表示の関係もありますので冗長してますが、
実質はscanfだけですね。
同じように、sprintfとかあの辺でもできまっせ。
では、開いたファイルは後始末をしましょう。
main.cpp
//ファイルのクローズの流れ*********************************************************************************
//Section1:アンマップ( マップビューの後始末 )
if( !UnmapViewOfFile( mapView ) )
{
printf( "アンマップできねーしー" ) ; //エラー
return 1;
}
//Section2:マッピングオブジェクトのクローズ
CloseHandle( hMap );
//Section3:ファイルのクローズ
CloseHandle( hFile );
|
見ての通り
超簡単に、ファイルの中身を書き換えることができます。
...が、実際にこの実行結果を触ってみると、ある、欠陥に気付くのではないかと、
そうです☆バチコーン
ファイルの中に最初から入ってた文字数しか扱えねーじゃん!
ってことです。
実は、ファイルをそのままマッピングする都合上、
このソ-スだとファイルのサイズ分しか
扱うことができません。
これの対処も踏まえた、メモリマップドファイルの活用法については、
また次回、
そ~れ~で~は~(*´∀`)ノ
以下に全体のソースを置いておきます。
右クリックで対象をファイルに保存
PR
COMMENT
無題
記事が長くなりそうなときは、続きに隠していただけると助かります。
スクロール量が増えてしまうので…
無題
すいませんーーー!!
直しました!
今後ともよろしくお願いします