2009年09月24日

第0x07回 データの保存〜ファイルアクセス〜

C言語の標準関数に定義されているファイルアクセスですが、
Win32APIでも、関数が定義されています。
どちらの関数を使っても、結局同一のWindowsネイティブの関数が呼び出されるので、
結果は同じですが、Win32APIの関数では、細かいオプション指定ができます。
まず、ざっとファイルアクセスに関する関数を見ていきましょう。


●ファイルオープン
HANDLE CreateFile(
LPCTSTR lpFileName, // ファイル名
DWORD dwDesiredAccess, // アクセスモード
DWORD dwShareMode, // 共有モード
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // セキュリティ記述子
DWORD dwCreationDisposition, // 作成方法
DWORD dwFlagsAndAttributes, // ファイル属性
HANDLE hTemplateFile // テンプレートファイルのハンドル
);

戻り値:ファイルのハンドル
(失敗時には、INVALID_HANDLE_VALUEが返る)
この関数は、ファイルのハンドルをオープンする関数です。
ファイルをロードする、ファイルを作成するなど、全ての処理は、
まずこの関数を呼び出し、ファイルハンドルをオープンしなければなりません。

dwDesiredAccessでは、オープンされるハンドルを用いて、どのようなアクセスをするか指定します。
アクセスモードとして、次の値が定義されています。
0             : デバイス属性のみアクセス
GENERIC_READ : 読み取りアクセス
GENERIC_WRITE : 書き込みアクセス

dwShareModeでは、オープンするファイルの共有方法を指定します。
この値を指定しない場合には、このファイルはロックされ、他のアプリケーションからアクセスできなくなります。
共有方法として、次の値が定義されています。
FILE_SHARE_READ   : ファイルの読み取りを許可する
FILE_SHARE_WRITE : ファイルの書き込みを許可する
FILE_SHARE_DELETE : ファイルの削除を許可する(Windows NT/2000以降)

dwCreationDispositionでは、ファイルの作成方法を指定します。
ファイルの作成方法として、次の値が定義されています。
CREATE_NEW     : 新しいファイルを作成します。指定したファイルが既に存在する場合、この関数は失敗します。
CREATE_ALWAYS : 新しいファイルを作成します。指定したファイルが既に存在する場合、上書きされます。
OPEN_EXISTING : ファイルを開きます。指定したファイルが存在しない場合、この関数は失敗します。
OPEN_ALWAYS : ファイルを開きます。指定したファイルが存在しない場合、CREATE_NEWと仮定し、新たに作成します。

dwFlagsAndAttributesでは、ファイルの属性を指定します。
属性として、次の値が定義されています。
FILE_ATTRIBUTE_ARCHIVE    : アーカイブ属性
FILE_ATTRIBUTE_ENCRYPTED : ファイル暗号化属性
FILE_ATTRIBUTE_HIDDEN : 隠しファイル属性
FILE_ATTRIBUTE_NORMAL : 通常ファイル属性
FILE_ATTRIBUTE_READONLY : 読み取り専用属性


●ファイルクローズ
BOOL CloseHandle( 
HANDLE hObject // オブジェクトのハンドル
);

戻り値:(成功時)0以外の値が返る (失敗時)0が返る
CreateFile()関数でオープンしたハンドルの使用が終了した時点で、
この関数を使い、ハンドルをクローズしなければなりません。
クローズしなかったハンドルは、リソースリークとして残り、そのハンドルの処理は未定義となります。


●データ読み取り
BOOL ReadFile(
HANDLE hFile, // ファイルのハンドル
LPVOID lpBuffer, // データバッファ
DWORD nNumberOfBytesToRead, // 読み取り対象のバイト数
LPDWORD lpNumberOfBytesRead, // 読み取ったバイト数
LPOVERLAPPED lpOverlapped // オーバーラップ構造体のバッファ
);

戻り値:(成功時)0以外の値が返る (失敗時)0が返る

ファイルハンドルを使用し、ファイルのデータを読み取ります。
lpBufferは、受け取るデータのバッファになります。
nNumberOfBytesToReadは、何バイトデータを読み取るかを指定します。
lpNumberOfBytesReadは、読み取ったデータのサイズが返されます。
nNumberOfBytesToReadより小さい値の場合、何らかのエラーが発生した可能性があります。


●データ書き込み
BOOL WriteFile(
HANDLE hFile, // ファイルのハンドル
LPCVOID lpBuffer, // データバッファ
DWORD nNumberOfBytesToWrite, // 書き込み対象のバイト数
LPDWORD lpNumberOfBytesWritten, // 書き込んだバイト数
LPOVERLAPPED lpOverlapped // オーバーラップ構造体のバッファ
);

戻り値:(成功時)0以外の値が返る (失敗時)0が返る

ファイルハンドルを使用し、ファイルにデータを書き込みます。
lpBufferは、書き込むデータのバッファになります。
以降は、基本的に読み取りと同じように指定します。


●ファイルポインタ移動
DWORD SetFilePointer(
HANDLE hFile, // ファイルハンドル
LONG lDistance, // 下位オフセット
PLONG pDistanceHigh, // 上位オフセットの変数
DWORD dwMoveMethod // 移動開始点
);

戻り値:成功時には、新しいファイルポインタの位置を示す
符号なし数値の下位32ビットが返ります。
(失敗時には、INVALID_SET_FILE_POINTERが返ります)
ファイルの読み書きするポイントを移動します。
dwMoveMethodは、移動開始点をします。
値は、次のように定義されています。
FILE_BEGIN   : ファイルの先頭を移動開始点にします
FILE_CURRENT : 現在のファイルポイントを移動開始点にします
FILE_END : ファイルの終端を移動開始点にします



さて、これらを踏まえて、前回までの環境設定の保存先をファイルに変更してみます。
サンプルは次のとおりになります。


(サンプル)
sample007.zip


以前までの処理を変更し、CConfigクラスに環境設定の処理を実装しました。
メンバ変数として、環境設定の内容を保持し、クラスの生成時、破棄時に、
それぞれ、ファイルのロード、セーブを行っています。
ファイルに保存することにより、環境設定の内容がアプリケーションを終了した状態でも
保持されることになります。


ラベル:ふわ猫
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。