antenn-a
company profile

MFC航海日記 八日日(ファイル操作)

今までインタフェースをいじってきたが、重要なのは目に映る部分ではなくその中身である。すなわちアプリケーション本体が腐っていたのでは仕方が無いという事だ。今日はその一部としてファイル操作をやってみたいと思う。アプリケーションにおいてファイルを使わない(作らない・読み込まない)事はほとんどありえない事である。様々なところでファイルにアクセスする事だと思う。例えば、設定の保存・呼び出し・データのバックアップなどその用途は計り知れない。
いままで、筆者はファイルを扱うときに FILE* を使用していた。FILE* を使用するに当たりいくつか面倒な事がある。例えば、fopen したならば fclose しなければ成らず、これをし忘れると大変な事になる。ひどいときはアプリケーション自体おっこちてしまう場合すらある。
そこで、MFCのクラス「CFILE」の使い方を勉強したいと思う。このクラスはファイルポインタを自動的に消滅させてくれるありがたいクラスである。CFILE クラス内の Write メンバー関数で保存を行いひead 関数で読み出しを行う。
筆者がいろいろ試したところ、大体の場合において通常通り使用できた・・・・・が!しかし!問題発生!一つだけ書き込みも読み出しも出来ない現象にであった!その時のソースを下に示す。

prev

void CTestDlg::OnRButtonDown(UINT nFlags, CPoint point) 
{
    CFile    fpw;
    CString  str;
    str = "test1";
    long     num = str.GetLength();

    fpw.Open( "test.txt", CFile::modeCreate | CFile::modeWrite );
    if( fpw == NULL ){
        ::MessageBox(*this, "", "", MB_OK);
        return;
    }
    fpw.Write( &str, num);
    fpw.Close();
  
    CDialog::OnRButtonDown(nFlags, point);
}

void CTestDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
    CFile   fp;
    CString   str;

    if( fp.Open( "test.txt", CFile::modeRead ) == NULL ){
        ::MessageBox(*this, "", "", MB_OK);
        return;
    }
    fp.Read( &str, 5 );
    fp.Close();

    CDialog::OnLButtonDown(nFlags, point);
}
Write 関数と Read の引数は const void* lpBuf, UINT nCount なのでこれでいいのかと思ったらだめだった そこで、CString のヘルプを見ると・・・・・なんと!CString は先頭から値が書き込まれているとは限らないというではないか!これではだめなはず・・・・なるほど・・・。
そこで、CString のオブジェクトから領域の確保と文字列の抜き出しを行い、書き込み・読み出しが終了した らそのバッファを開放するという手順で事を運ぶ事にした。そのソースコードを下記に示す。
void CFileAccessDlg::OnBtnWrite() 
{
    CString   str;
    LPTSTR    pszBuf;
    long      size;

    CFile     fpw( "FileAccess.txt",
    CFile::modeCreate | CFile::modeWrite |
    CFile::shareExclusive );

    m_Edt.GetWindowText( str );

    size = str.GetLength();

    fpw.Write( &size, sizeof( long ) );
    //バッファの確保
    pszBuf = str.GetBuffer( size );
    //書き込み
    fpw.Write( pszBuf, size );
    //バッファの開放
    str.ReleaseBuffer();

    //エディットボックスのクリア
    m_Edt.SetWindowText( "" );
}

void CFileAccessDlg::OnBtnRead() 
{
    CString     str;
    long        size;

    CFile       fp( "FileAccess.txt",
    CFile::modeRead | CFile::shareExclusive );
  
    fp.Read( &size, sizeof( long ) );
    //バッファの確保
    fp.Read( (void*)str.GetBuffer( size ), size );
    //読み出し
    m_Edt.SetWindowText( str );
    //バッファの開放
    str.ReleaseBuffer();
}

prev

こんな感じで無事ファイル操作が出来るようになった。CString は非常に便利なクラスなだけに使い方をマスターしておかないととんでもないところで詰まったりするものだ・・・・ふぅ、よかった・・・・。 このサンプルはここからダウンロードできる。


antenn-a

prev next


antenn-a