MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
MFCの基礎 - ファイルのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
MFCの基礎 - ファイル
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== ファイルを開く == <code>CFile</code>クラスの<code>Open</code>メソッドは、第1引数はファイル名、第2引数はファイルモードを指定する。<br> <syntaxhighlight lang="c++"> CFile File; if(File.Open(_T("test.dat"), CFile::modeCreate| CFile::modeNoTruncate | CFile::modeWrite | CFile::typeBinary)) { // To do something } file.Close(); </syntaxhighlight> <br> 主なモードを以下に記載する。<br> <center> {| class="wikitable" style="background-color:#fefefe;" |- ! style="background-color:#00ffff;" | モード名 ! style="background-color:#00ffff;" | 説明 |- | CFile::modeCreate || ファイルを新規に作成する。<br>既にファイルがある場合は、削除して新規に作成する。 |- | CFile::modeNoTruncate || modeCreateと組み合わせて使用する場合、<br>既にファイルがある場合は新規作成せずに開く。 |- | CFile::modeRead || ファイルを読み取り専用で開く。 |- | CFile::modeReadWrite || ファイルを読み書き可能で開く。 |- | CFile::modeWrite || ファイルを書き込み専用で開く。 |- | CFile::shareDenyNone || 他プロセスからも読み書きできる状態でファイルを開く。 |- | CFile::shareExclusive || ファイルを排他モードで開く。 |- | CFile::typeText || テキストモードを設定する。<br>派生クラスで使用する。 |- | CFile::typeBinary || バイナリモードを設定する。<br>派生クラスで使用する。 |} </center> <br><br> == 1行ずつ読み込む == <syntaxhighlight lang="c++"> CStdioFile File(_T("test.dat"), CFile::modeCreate| CFile::modeNoTruncate | CFile::modeRead | CFile::typeText); CString strReadLine = _T(""); while(File.ReadString(strReadLine)) { TRACE(strReadLine + _T("\n")); } </syntaxhighlight> <br><br> == ファイルに書き込む == <syntaxhighlight lang="c++"> CStdioFile File(_T("test.dat"), CFile::modeCreate| CFile::modeNoTruncate | CFile::modeWrite | CFile::typeText); CString strWriteLine1 = _T("hoge\n"); File.WriteString(strWriteLine1); CString strWriteLine2 = _T("piyo\n"); File.WriteString(strWriteLine2); File.Close(); </syntaxhighlight> <br><br> == ファイルに追記する == CFileおよびCStdioFileには追記モードが存在しないので、ファイルを開いた後、書き込み位置を指定する必要がある。 下記のサンプルコードでは、ファイルを書き込みモードで開いた後、SeekToEndメソッドで書き込み位置を最後尾に移動する。 <syntaxhighlight lang="c++"> CStdioFile File(_T("test.dat"), CFile::modeCreate| CFile::modeNoTruncate | CFile::modeWrite | CFile::typeText); File.SeekToEnd(); // 書き込み位置を最後尾に移動 CString strWriteLine1 = _T("hoge\n"); File.WriteString(strWriteLine1); // Write a line CString strWriteLine2 = _T("piyo\n"); File.WriteString(strWriteLine2); // Write a line File.Close(); </syntaxhighlight> <br><br> == ファイルを削除する == <syntaxhighlight lang="c++"> // 単一のファイルを削除する CFile::Remove(_T("C:\\test.txt")); // Cドライブ直下のtest.txtファイルを削除する </syntaxhighlight> <br> <syntaxhighlight lang="c++"> // 複数のファイルやディレクトリを削除する CString strRemoveDirPath = _T("C:\\test?"); strRemoveDirPath.SetAt(strRemoveDirPath.GetLength() - 1, 0); SHFILEOPSTRUCT drive = {}; drive.hwnd = this->m_hWnd; // ウィンドウハンドル drive.wFunc = FO_DELETE; // 実行する操作 drive.pFrom = strRemoveDirPath; // 対象ファイル名 drive.pTo = NULL; // 目的ファイル名 drive.fFlags = FOF_ALLOWUNDO; // フラグ SHFileOperation(&drive); </syntaxhighlight> wFuncは、下記に示す通り、実行する操作を指定する。<br> <center> {| class="wikitable" style="background-color:#fefefe;" |- ! style="background-color:#00ffff;" | 命令マクロ ! style="background-color:#00ffff;" | 説明 |- | FO_MOVE || pFromをpToの位置に移動 |- | FO_COPY || pFromをpToの位置にコピー |- | FO_DELETE || Fromを削除 |- | FO_RENAME || pFromをpToに変更 |} </center> pFromにはディレクトリおよびファイルを指定する。ワイルドカードも使用できる。<br> また、NULL文字(\0)で区切ると複数指定できる。<br> <br> fFlagは、下記に示す通り、動作時のフラグを指定する。<br> <center> {| class="wikitable" style="background-color:#fefefe;" |- ! style="background-color:#00ffff;" | 命令マクロ ! style="background-color:#00ffff;" | 説明 |- | FOF_SILENT || 経過を表すダイアログボックス非表示 |- | FOF_ALLOWUNDO || 削除の場合はゴミ箱に移動 |- | FOF_NOERRORUI || エラーが発生した場合はUI非表示 |- | FOF_NOCONFIRMATION || 表示されるダイアログボックスで『はい』または『すべて』を選択する |} </center> <br><br> == ファイル / ディレクトリのコピー・移動・削除 == <syntaxhighlight lang="c++"> // ファイルのコピー BOOL CopyFile( LPCTSTR lpExistingFileName, // コピー元のファイルのパス LPCTSTR lpNewFileName, // コピー先のファイルのパス BOOL bFailIfExists // 上書き許可 / 不許可 ); // ファイルの移動・ファイル名の変更 BOOL MoveFile( LPCTSTR lpExistingFileName, // 移動元のファイルのパス LPCTSTR lpNewFileName // 移動後のファイルのパス ); // ファイルの削除 BOOL DeleteFile( LPCTSTR lpFileName // 削除するファイルのパス ); </syntaxhighlight> <br><br> == ファイル / ディレクトリの属性の取得・設定 == <syntaxhighlight lang="c++"> // ファイルおよびディレクトリの属性の取得 DWORD GetFileAttributes( LPCTSTR lpFileName // ファイルのパス ); // ファイルおよびディレクトリの属性の設定 BOOL SetFileAttributes( LPCTSTR lpFileName, // ファイルのパス DWORD dwAttributes // 属性フラグ ); </syntaxhighlight> <br> <center> {| class="wikitable" style="background-color:#fefefe;" |+ 属性の定数 |- ! style="background-color:#66CCFF;" | 定数 ! style="background-color:#66CCFF;" | 意味 |- | FILE_ATTRIBUTE_NORMAL || 特に属性なし |- | FILE_ATTRIBUTE_ARCHIVE || アーカイブ属性 |- | FILE_ATTRIBUTE_READONLY || 読み取り専用の属性 |- | FILE_ATTRIBUTE_HIDDEN || 隠しファイルの属性 |- | FILE_ATTRIBUTE_SYSTEM || システムファイルの属性 |- | FILE_ATTRIBUTE_DIRECTORY || ディレクトリの属性 |} </center> <br> <code>FILE_ATTRIBUTE_NORMAL</code>属性は、他の属性定数と組み合わせて使用できない。<br> <code>FILE_ATTRIBUTE_DIRECTORY</code>属性は、属性を指定しても設定できない。<br> <br><br> == ファイルのタイプの取得 == <syntaxhighlight lang="c++"> DWORD GetFileType( HANDLE hFile // ファイルのハンドル ); </syntaxhighlight> <br> 以下の例では、変数hFileにファイルのハンドルを指定する。<br> <code>GetFileType</code>関数を使用して、コンソールの標準入出力等でリダイレクションされたかどうかを確認することができる。<br> <syntaxhighlight lang="c++"> // ファイルのタイプの判定 switch(GetFileType(hFile)) { CASE FILE_TYPE_UNKNOWN: printf(TEXT("ファイルのタイプは不明\n")); break; CASE FILE_TYPE_DISK: printf(TEXT("ファイルのタイプはディスク上のファイル\n")); break; CASE FILE_TYPE_CHAR: printf(TEXT("ファイルのタイプはデバイスまたはコンソール\n")); break; CASE FILE_TYPE_PIPE: printf(TEXT("ファイルのタイプは名前付きまたは名前なしパイプ\n")); break; DEFAULT: printf(TEXT("GetFileType関数の致命的なエラー\n")); break; } </syntaxhighlight> <br> <center> {| class="wikitable" style="background-color:#fefefe;" |+ 戻り値の定数 |- ! style="background-color:#66CCFF;" | 定数 ! style="background-color:#66CCFF;" | 意味 |- | FILE_TYPE_UNKNOWN || ファイルのタイプは不明 |- | FILE_TYPE_DISK || ファイルのタイプはディスク上のファイル |- | FILE_TYPE_CHAR || ファイルのタイプはデバイスまたはコンソール |- | FILE_TYPE_PIPE || ファイルのタイプは、名前付きパイプまたは名前なしパイプ |} </center> <br><br> == ファイルサイズの取得 == ==== GetFileSize関数 ==== <syntaxhighlight lang="c++"> DWORD GetFileSize( HANDLE hFile, // ファイルのハンドル LPDWORD lpFileSizeHigh // ファイルサイズの上位ワード ); </syntaxhighlight> <br> 以下の例では、変数hFileにファイルのハンドルを指定して、<br> 4[GB]以下のファイルの場合、GetFileSize関数の戻り値をそのまま受け取り、4[GB]以上のファイルの場合、上位ワードのポインタを第2引数に渡している。<br> その後、64ビット整数の変数等に代入して使用する。<br> <syntaxhighlight lang="c++"> // 4[GB]以下のファイルサイズの取得 DWORD dwSize = GetFileSize(hFile, NULL); // 4[GB]以上のファイルサイズの取得 DWORDLONG dllSize = 0; // 64ビット整数 DWORD dwSize = 0; // 下位ワード DWORD dwHigh = 0; // 上位ワード dwSize = GetFileSize(hFile, &dwHigh); dllSize = (((DWORDLONG)dwHigh << 32) | dwSize); </syntaxhighlight> <br> ==== GetFileSizeEx関数 ==== 4[GB]以上のファイルサイズを取得する場合、<code>GetFileSizeEx</code>関数も使用できる。<br> <syntaxhighlight lang="c++"> BOOL GetFileSizeEx( HANDLE hFile, // ファイルのハンドル LPLARGE_INTEGER lpFileSize // ファイルサイズの構造体 ); </syntaxhighlight> <br> LARGE_INTEGER構造体を、以下に示す。<br> <syntaxhighlight lang="c++"> typedef union _LARGE_INTEGER { struct { DWORD LowPart; // 下位32ビット LONG HighPart; // 上位32ビット }; struct { DWORD LowPart; // 下位32ビット LONG HighPart; // 上位32ビット } u; LONGLONG QuadPart; // 64ビット整数 } LARGE_INTEGER, *LPLARGE_INTEGER; </syntaxhighlight> <br> 以下の例では、変数hFileにファイルのハンドルを指定して、ファイルサイズを64ビット整数で表示している。<br> また、<code>printf</code>関数がC99規格に準じている場合は、<code>%lld</code>を指定することで64ビット整数を表示できる。<br> <syntaxhighlight lang="c++"> LARGE_INTEGER i64Size = 0; GetFileSizeEx(hFile, &i64Size); printf(TEXT("ファイルサイズ : %I64ld\n"), i64Size.QuadPart); // または // printf(TEXT("ファイルサイズ : %lld\n"), i64Size.QuadPart); </syntaxhighlight> <br><br> == ファイルが実行可能かどうか確認する == <syntaxhighlight lang="c++"> BOOL GetBinaryType( LPCTSTR lpApplicationName, // ファイルのパス LPDWORD lpBinaryType // バイナリタイプ情報 ); </syntaxhighlight> <br> 以下の例では、<code>GetBinaryType</code>関数を使用して、ファイルが実行可能かどうかを確認している。<br> バッチファイル(*.bat)やDLLファイルは実行可能とは判定しない。<br> <syntaxhighlight lang="c++"> DWORD dwType = 0; GetBinaryType(TEXT("C:\\Windows\\System32\\calc.exe"), &dwType); switch(dwType) { case SCS_32BIT_BINARY: printf(TEXT("Win32ベースのアプリケーション\n")); break; case SCS_DOS_BINARY: printf(TEXT("MS-DOSベースのアプリケーション\n")); break; case SCS_OS216_BINARY: printf(TEXT("16ビット版OS/2ベースのアプリケーション\n")); break; case SCS_PIF_BINARY: printf(TEXT("MS-DOSベースのアプリケーションを実行するPIFファイル\n")); break; case SCS_POSIX_BINARY: printf(TEXT("POSIXベースのアプリケーション\n")); break; case SCS_WOW_BINARY: printf(TEXT("16ビット版Windowsベースのアプリケーション\n")); break; default: printf(TEXT("GetFileType関数の致命的なエラー\n")); break; } </syntaxhighlight> <br><br> == タイムスタンプの取得 / 設定 == ==== タイムスタンプの取得 ==== この関数群は、ディレクトリも同様にタイムスタンプを取得できる。<br> <syntaxhighlight lang="c++"> // タイムスタンプの取得 BOOL GetFileTime( HANDLE hFile, // ファイルのハンドル LPFILETIME lpCreationTime, // 作成日時 LPFILETIME lpLastAccessTime, // 最終アクセス日時 LPFILETIME lpLastWriteTime // 最終更新日時 ); // タイムスタンプからローカル時間に変換 BOOL FileTimeToLocalFileTime( CONST FILETIME* lpFileTime, // 世界標準時間のファイル時刻 LPFILETIME lpLocalFileTime // ローカル時間のファイル時刻 ); // タイムスタンプからシステム時間に変換 BOOL FileTimeToSystemTime( CONST FILETIME* lpFileTime, // 変換前のファイル時刻 LPSYSTEMTIME lpSystemTime // 変換後のシステム日時 ); </syntaxhighlight> <br> <code>FILETIME</code>構造体および<code>SYSTEMTIME</code>構造体を、以下に示す。<br> <syntaxhighlight lang="c++"> typedef struct _FILETIME { DWORD dwLowDateTime; // 下位32ビット DWORD dwHighDateTime; // 上位32ビット } FILETIME, *PFILETIME; typedef struct _SYSTEMTIME { WORD wYear; // 年(1901~) WORD wMonth; // 月(1-12) WORD wDayOfWeek; // 曜日(0-6) WORD wDay; // 日(1-31) WORD wHour; // 時(0-23) WORD wMinute; // 分(0-59) WORD wSecond; // 秒(0-59) WORD wMilliseconds; // ミリ秒(0-999) } SYSTEMTIME, *PSYSTEMTIME; </syntaxhighlight> <br> 以下の例では、変数hFileにファイルのハンドルを指定して、タイムスタンプを取得している。<br> ディレクトリの場合は、<code>FILE_FLAG_BACKUP_SEMANTICS</code>フラグを指定する。<br> <syntaxhighlight lang="c++"> FILETIME ft1, ft2, ft3; // ファイル時刻 FILETIME lt1, lt2, lt3; // ローカル時刻 SYSTEMTIME st1, st2, st3; // システム日時 // ファイル日時の取得 GetFileTime( hFile, &ft1, &ft2, &ft3 ); // ファイル時刻からローカル時刻に変換 FileTimeToLocalFileTime( &ft1, <1 ); // 作成日時 FileTimeToLocalFileTime( &ft2, <2 ); // 最終アクセス日時 FileTimeToLocalFileTime( &ft3, <3 ); // 最終更新日時 // ローカル時刻からシステム日時に変換 FileTimeToSystemTime( <1, &st1 ); // 作成日時 FileTimeToSystemTime( <2, &st2 ); // 最終アクセス日時 FileTimeToSystemTime( <3, &st3 ); // 最終更新日時 // 作成日時をprintf()で表示 printf(TEXT("%04d/%02d/%02d (%d) %02d:%02d:%02d.%03d\n"), st1.wYear, // 年(1901-) st1.wMonth, // 月(1-12) st1.wDay, // 日(1-31) st1.wDayOfWeek, // 曜日(0-6) st1.wHour, // 時(0-23) st1.wMinute, // 分(0-59) st1.wSecond, // 秒(0-59) st1.wMilliseconds // ミリ秒(0-999) ); </syntaxhighlight> <br> ==== タイムスタンプの設定 ==== この関数群は、ディレクトリも同様にタイムスタンプを設定できる。<br> <br> <syntaxhighlight lang="c++"> // システム時間からファイル日時に変換 BOOL SetFileTime( HANDLE hFile, // ファイルのハンドル CONST FILETIME* lpCreationTime, // 作成日時 CONST FILETIME* lpLastAccessTime, // 最終アクセス日時 CONST FILETIME* lpLastWriteTime // 最終更新日時 ); // ローカル時間からファイル日時に変換 BOOL LocalFileTimeToFileTime( CONST FILETIME* lpLocalFileTime, // ローカル時間のファイル時刻 LPFILETIME lpFileTime // 世界標準時間のファイル時刻 ); // ファイル日時の設定 BOOL SystemTimeToFileTime( CONST SYSTEMTIME* lpSystemTime, // 変換前のシステム日時 LPFILETIME lpFileTime // 変換後のファイル時刻 ); </syntaxhighlight> <br> FILETIME構造体およびSYSTEMTIME構造体を、以下に示す。<br> <syntaxhighlight lang="c++"> typedef struct _FILETIME { DWORD dwLowDateTime; // 下位32ビット DWORD dwHighDateTime; // 上位32ビット } FILETIME, *PFILETIME; typedef struct _SYSTEMTIME { WORD wYear; // 年(1901~) WORD wMonth; // 月(1-12) WORD wDayOfWeek; // 曜日(0-6) WORD wDay; // 日(1-31) WORD wHour; // 時(0-23) WORD wMinute; // 分(0-59) WORD wSecond; // 秒(0-59) WORD wMilliseconds; // ミリ秒(0-999) } SYSTEMTIME, *PSYSTEMTIME; </syntaxhighlight> <br> 以下の例では、変数hFileにファイルのハンドルを指定して、タイムスタンプを設定している。<br> ディレクトリの場合は、<code>FILE_FLAG_BACKUP_SEMANTICS</code>フラグを指定する。<br> <u>このフラグを指定しない場合、正常に処理できないことに注意する。</u><br> <syntaxhighlight lang="c++"> FILETIME ft1, ft2, ft3; // ファイル時刻 FILETIME lt1, lt2, lt3; // ローカル時刻 SYSTEMTIME st1, st2, st3; // システム日時 // 現在の日時を構造体にセット GetLocalTime(&st1); GetLocalTime(&st2); GetLocalTime(&st3); // システム日時からローカル時刻に変換 SystemTimeToFileTime(&st1, <1); // 作成日時 SystemTimeToFileTime(&st2, <2); // 最終アクセス日時 SystemTimeToFileTime(&st3, <3); // 最終更新日時 // ローカル時刻からファイル時刻に変換 LocalFileTimeToFileTime(<1, &ft1); // 作成日時 LocalFileTimeToFileTime(<2, &ft2); // 最終アクセス日時 LocalFileTimeToFileTime(<3, &ft3); // 最終更新日時 // ファイル日時の設定 SetFileTime(hFile, &ft1, &ft2, &ft3); </syntaxhighlight> <br><br> == ファイル / ディレクトリの検索 == <syntaxhighlight lang="c++"> // 最初のファイルを検索 HANDLE FindFirstFile( LPCTSTR lpFileName, // ファイルのパス LPWIN32_FIND_DATA lpFindFileData // データバッファ ); // 次のファイルを検索 BOOL FindNextFile( HANDLE hFindFile, // 検索ハンドル LPWIN32_FIND_DATA lpFindFileData // データバッファ ); // ファイル検索を終了する BOOL FindClose( HANDLE hFindFile // 検索ハンドル ); </syntaxhighlight> <br> LPWIN32_FIND_DATA構造体を以下に示す。<br> <syntaxhighlight lang="c++"> typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; // 属性 FILETIME ftCreationTime; // 作成日時 FILETIME ftLastAccessTime; // 最終アクセス日時 FILETIME ftLastWriteTime; // 最終更新日時 DWORD nFileSizeHigh; // サイズ(上位ワード) DWORD nFileSizeLow; // サイズ(下位ワード) DWORD dwReserved0; // 予約領域 DWORD dwReserved1; // 予約領域 TCHAR cFileName[ MAX_PATH ]; // ファイル名 TCHAR cAlternateFileName[ 14 ]; // 8.3形式のファイル名 } WIN32_FIND_DATA, *PWIN32_FIND_DATA; </syntaxhighlight> <br> 以下の例では、<code>WIN32_FIND_DATA</code>構造体の<code>cFileName</code>メンバ変数に、ファイルやディレクトリのパスが代入されている。<br> <syntaxhighlight lang="c++"> // カレントディレクトリのファイル検索 void findDirectory() { WIN32_FIND_DATA fdFile = {0}; HANDLE hFind; if((hFind = FindFirstFile(TEXT("*.*"),&fdFile)) != INVALID_HANDLE_VALUE) { do { if(fdFile.cFileName[0] != TEXT('.') || fdFile.cFileName[0] != TEXT('..')) { if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // fdFile.cFileNameにディレクトリ名 } else { // fdFile.cFileNameにファイル名 } } }while(FindNextFile(hFind, &fdFile)); FindClose(hFind); } } </syntaxhighlight> <br><br> == ファイルの再帰検索 == 以下の例では、指定したディレクトリに存在する全てのファイルを再帰検索している。<br> <syntaxhighlight lang="c++"> // 関数内で自分自身を呼び出す再帰関数を作る void CSampleView::SerchFiles(CString Path) { // ファイルの検索 CFileFind Finder; Path += _T("\\*.*"); BOOL bWorking = Finder.FindFile(Path, 0); while(bWorking) { bWorking = Finder.FindNextFile(); CString Getpath = Finder.GetFilePath(); CString Getname = Finder.GetFileName(); // 再帰的にディレクトリアイテムを作成 if(!(GetFileAttributes(Getpath) & FILE_ATTRIBUTE_DIRECTORY)) { // ファイルの場合 } else { if(Getname != _T(".") && Getname != _T("..")) { // ディレクトリの場合 SerchFiles(Getpath); } } } } </syntaxhighlight> <br> 例えば、以下のようにSerchFilesメソッドを呼べば、次のようにDドライブの内容を全て書き出す。<br> <syntaxhighlight lang="c++"> SerchFiles(_T("D:\\")) </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:MFC]]
MFCの基礎 - ファイル
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse