「MFCの基礎 - ファイル」の版間の差分

ナビゲーションに移動 検索に移動
編集の要約なし
135行目: 135行目:
|}
|}
</center>
</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>
== ファイル / ディレクトリの検索 ==
<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><br>


案内メニュー