ホーム > デベロッパ > BREW プログラミング入門 > ファイルを操作してみよう > - 2 / 3 -

ファイルを操作してみよう - 2 / 3 -

空ではないディレクトリを削除する方法

次に上記コードを改造して、指定されたディレクトリが空でなくても削除を行う関数を作成してみましょう。

static void RmDirRecursive(FilesystemApplet* app,const char* name)
{
  IShell*  shell = app->a.m_pIShell;
  IFileMgr*  filemgr;
  FileInfo  info;
  // IFileMgr インタフェースの作成
  ISHELL_CreateInstance(shell,AEECLSID_FILEMGR,(void*)&filemgr);
  // 列挙をディレクトリ用に初期化
  IFILEMGR_EnumInit(filemgr,name,TRUE);
  // 次の要素を取得
  while (IFILEMGR_EnumNext(filemgr,&info)) {
    // ディレクトリの中を再帰的に巡回
    RmDirRecursive(app,info.szName);
  }
  // 列挙をファイル用に初期化
  IFILEMGR_EnumInit(filemgr,name,FALSE);
  // 次の要素を取得
  while (IFILEMGR_EnumNext(filemgr,&info)) {
    // ファイルの削除
    IFILEMGR_Remove(filemgr,info.szName);
  }
  // ディレクトリの削除
  IFILEMGR_RmDir(filemgr,name);
  // IFileMgr インタフェースの破棄
  IFILEMGR_Release(filemgr);
  return;
}
// 呼び出し
RmDirRecursive(app,"target_dir");

上記コードの RmDirRecursive 関数を使用すると、空でないディレクトリも削除することができます。上記コードでは "target_dir" ディレクトリを削除しています。もしも間違えて "" と指定して呼び出したら大変です。アプリの実体と同じディレクトリ内の全てのファイル(削除可能なものだけ)が削除されてしまいます。実験するときは注意しましょう。

※上記コードをエミュレータ上で動作させる場合、 "target_dir" ディレクトリを Windows のエクスプローラなどで開いていると正常に削除できない場合があります。

ファイルを操作してみる

ここまではディレクトリの操作の方法を解説してきました。それでは次に、 IFile インタフェースを使用したファイルの操作の方法について解説します。

IFile インタフェースには以下のような API が存在します。ファイルの操作は、これらの API を使用して行います。

関数名 解説
IFILE_GetInfo ファイルの情報を取得します。
IFILE_GetInfoEx ファイルの拡張情報を取得します。
IFILE_Read ファイルからデータを読み込みます。
IFILE_Readable ファイルが読み込み可能になるまで読み込みをペンディングします。
IFILE_Write ファイルへデータを書き出します。
IFILE_Cancel IFILE_Readable 関数によって登録されたコールバックをキャンセルします。
IFILE_Seek ファイルのアクセス位置を変更します。
IFILE_Truncate ファイルを切り詰めます。
IFILE_SetCacheSize IFile インタフェースの内部バッファリング用のキャッシュサイズを設定します。

※上記表は、頻繁に使用されるAPIしか列挙していません。より、詳しい情報は BREW API リファレンスを参照してください。

ファイルのオープンとクローズ

BREW でファイルの内容を読み書きするためにファイルをオープンするには、 IFileMgr インタフェースの IFILEMGR_OpenFile 関数を使用します。また、オープンされたファイルをクローズするには、 IFile インタフェースの IFILE_Release 関数を使用します。 IFILEMGR_Close 関数や IFILE_Close 関数などは存在しません。では、以下に新しいファイル作成した後、オープンしてクローズするコードを示します。

IShell*  shell = app->a.m_pIShell;
IFileMgr*  filemgr;
IFile*  file;
// IFileMgr インタフェースの作成
ISHELL_CreateInstance(shell,AEECLSID_FILEMGR,(void*)&filemgr);
// ファイルの新規オープン
file = IFILEMGR_OpenFile(filemgr,"sample.txt",_OFM_CREATE);
// ファイルのクローズ
IFILE_Release(file);
// IFileMgr インタフェースの破棄
IFILEMGR_Release(filemgr);

※上記コードは "sample.txt" という名前のファイルが既に存在する場合は正常にファイルをオープンすることができません。詳細は以下のオープンモードの表を参照してください。

ここで IFILEMGR_OpenFile 関数の第 3 引数はファイルをオープンするときのモードを表します。 BREW で使用できるオープンモードには以下のようなものがあります。

モード 解説
_OFM_READ ファイルを読み込みモードでオープンする。ファイルが存在しない場合は作成しない。
_OFM_READWRITE ファイルを読み込み / 書き込みモードでオープンする。ファイルが存在しない場合は作成しない。
_OFM_APPEND ファイルを読み込み / 書き込みモードでオープンするが、あらかじめアクセス位置をファイルの末尾に移動させる。ファイルが存在しない場合は作成しない。
_OFM_CREATE ファイルを読み込み / 書き込みモードで作成する。既にファイルが存在する場合はファイルがオープンされることはなく、エラーとなる。

では、ファイルが存在しないときはファイルを作成してオープンし、ファイルが存在するときはファイルをオープンできるように、コードを改良してみましょう。

IShell*  shell = app->a.m_pIShell;
IFileMgr*  filemgr;
IFile*  file;
// IFileMgr インタフェースの作成
ISHELL_CreateInstance(shell,AEECLSID_FILEMGR,(void*)&filemgr);
// ファイルのオープン
file = IFILEMGR_OpenFile(filemgr,"sample.txt",_OFM_READWRITE);
// ファイルが存在しなかった場合
if (file == NULL) {
  // ファイルの新規オープン
  file = IFILEMGR_OpenFile(filemgr,"sample.txt",_OFM_CREATE);
}
// ファイルのクローズ
IFILE_Release(file);
// IFileMgr インタフェースの破棄
IFILEMGR_Release(filemgr);

まず、ファイルを読み書きモードでオープンし、失敗した場合、作成モードでオープンを試みるように修正しました。より、安全なファイル処理を行いたい場合は、 IFILEMGR_GetLastError 関数を使用して具体的なエラー内容に応じて処理を変更します。

ファイルの情報を取得してみる

BREW にはディレクトリやファイルの情報を取得するための API があります。それらの API は FileInfo 構造体や AEEFileInfoEx 構造体に情報を詰め込んで結果を返してくれます。 FileInfo 構造体はファイルの属性やファイルが作成された日時、ファイルサイズ、ファイル名などが格納されています。また、 AEEFileInfoEx 構造体はそれらの情報に加えて、ファイルの説明やファイルの所有者などの情報が格納されています。普通 FileInfo 構造体を使用する事が多いと思いますので、ここでは FileInfo 構造体を使用したコードを示します。

IShell*  shell = app->a.m_pIShell;
IFileMgr*  filemgr;
IFile*  file;
FileInfo  info;
// IFileMgr インターフェースの作成
ISHELL_CreateInstance(shell,AEECLSID_FILEMGR,(void*)&filemgr);
// ファイルのオープン
file = IFILEMGR_OpenFile(filemgr,"sample.txt",_OFM_READ);
// ファイル情報の取得
IFILE_GetInfo(file,&info);
// ファイル情報の出力
DBGPRINTF("name : %s, size : %06d bytes",info.szName,info.dwSize);
// ファイルのクローズ
IFILE_Release(file);
// IFileMgr インターフェースの破棄
IFILEMGR_Release(filemgr);

いちいちファイルをオープンしなくても情報を取得することができます。

IShell*  shell = app->a.m_pIShell;
IFileMgr*  filemgr;
FileInfo  info;
// IFileMgr インターフェースの作成
ISHELL_CreateInstance(shell,AEECLSID_FILEMGR,(void*)&filemgr);
// ファイル情報の取得
IFILEMGR_GetInfo(filemgr,"sample.txt",&info);
// ファイル情報の出力
DBGPRINTF("name : %s, size : %06d bytes",info.szName,info.dwSize);
// IFileMgr インターフェースの破棄
IFILEMGR_Release(filemgr);