忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

WindowsAPI講座【メモリマップドファイル編】 Part2

こんにちは、克兎です。

記事を書いてる途中で、
ブラウザが停止したけど何なの?
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

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

無題

  • by とある2年
  • 2012/03/15(Thu)12:39
  • Edit
お疲れさまです。

記事が長くなりそうなときは、続きに隠していただけると助かります。

スクロール量が増えてしまうので…

無題

  • by 克兎
  • 2012/03/15(Thu)12:51
  • Edit
>>とある2年さん

すいませんーーー!!
直しました!
今後ともよろしくお願いします

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]