ファイル

ファイルのオープン

CreateFile()

ファイルを作成または開き、そのファイルへアクセスするためのハンドルを取得できます。

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

この関数には文字コードによって、次の2種類があります。

  • Unicode版 … CreateFileW
  • ANSI版 … CreateFileA
アクセスモード
 
GENERIC_READ 読み込み
GENERIC_WRITE 書き込み
共有モード
   
FILE_SHARE_DELETE  
FILE_SHARE_READ  
FILE_SHARE_WRITE  

ファイルが存在しないときの挙動は、dwCreationDispositionの値によります。

作成方法
   
CREATE_ALWAYS  
CREATE_NEW  
OPEN_ALWAYS  
OPEN_EXISTING  
TRUNCATE_EXISTING  

ファイルへの書き込み

BOOL WriteFile(
  HANDLE       hFile,
  LPCVOID      lpBuffer,
  DWORD        nNumberOfBytesToWrite,
  LPDWORD      lpNumberOfBytesWritten,
  LPOVERLAPPED lpOverlapped
);
WriteFile function | Microsoft Learn
int lpBuffer[] = { 1, 2, 3 };
const WCHAR* lpFileName = L"C:\\sample.bin";

HANDLE hFile = CreateFile(
    lpFileName,
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    CREATE_ALWAYS,
    0,
    NULL
);

DWORD nNumberOfBytesToWrite = sizeof(lpBuffer);
DWORD lpNumberOfBytesWritten;

BOOL bResult = WriteFile(
    hFile,
    lpBuffer,
    nNumberOfBytesToWrite,
    &lpNumberOfBytesWritten,
    NULL
);

CloseHandle(hFile);

ファイルの属性

GetFileAttributes()

ファイルの属性を取得できます。

DWORD WINAPI GetFileAttributes(
  _In_ LPCTSTR lpFileName
);
GetFileAttributes function (Windows) | MSDN GetFileAttributes 関数 | MSDN
LPCTSTR path = L"C:\\sample.txt";
DWORD attributes = GetFileAttributes(path);

結果は、下表の定数を含む値で返されます。

定数 属性名 説明
FILE_ATTRIBUTE_ARCHIVE 32 (0x20) A アーカイブ属性
FILE_ATTRIBUTE_COMPRESSED 2048 (0x800) C 圧縮属性
FILE_ATTRIBUTE_DEVICE 64 (0x40)   (システムが利用するために予約)
FILE_ATTRIBUTE_DIRECTORY 16 (0x10) D ディレクトリ (フォルダ) 属性
FILE_ATTRIBUTE_ENCRYPTED 16384 (0x4000) E 暗号化属性
FILE_ATTRIBUTE_HIDDEN 2 (0x2) H 隠しファイル属性
FILE_ATTRIBUTE_INTEGRITY_STREAM 32768 (0x8000) V 整合性属性 (ReFSボリュームのみでサポート).

Windows Server 2012より前はサポートされない

FILE_ATTRIBUTE_NORMAL 128 (0x80)   他の属性なし
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 8192 (0x2000) I (N) 非インデックス対象ファイル属性
FILE_ATTRIBUTE_NO_SCRUB_DATA 131072 (0x20000) X スクラブ ファイルなし属性

Windows 8とWindows Server 2012より前はサポートされない

FILE_ATTRIBUTE_OFFLINE 4096 (0x1000) O オフライン属性
FILE_ATTRIBUTE_READONLY 1 (0x1) R 読み取り専用属性
FILE_ATTRIBUTE_REPARSE_POINT 1024 (0x400) L リパースポイント
FILE_ATTRIBUTE_SPARSE_FILE 512 (0x200) P スパースファイル
FILE_ATTRIBUTE_SYSTEM 4 (0x4) S システム属性
FILE_ATTRIBUTE_TEMPORARY 256 (0x100) T 一時ファイル
FILE_ATTRIBUTE_VIRTUAL 65536 (0x10000)   (システムが利用するために予約)
File Attribute Constants (Windows) | MSDN

ディレクトリかどうかの判定

LPCTSTR path = L"C:\\sample";
DWORD attributes = GetFileAttributes(path);

if (attributes == INVALID_FILE_ATTRIBUTES)
{
    // 失敗
}
else if (attributes & FILE_ATTRIBUTE_DIRECTORY)
{
    // ディレクトリ
}
else
{
    // ディレクトリ以外
}
How to check if directory exist using C++ and winAPI - Stack Overflow

GetFileAttributesEx()

BOOL WINAPI GetFileAttributesEx(
  _In_  LPCTSTR                lpFileName,
  _In_  GET_FILEEX_INFO_LEVELS fInfoLevelId,
  _Out_ LPVOID                 lpFileInformation
);
GetFileAttributesEx function (Windows) | MSDN GetFileAttributesEx 関数 | MSDN
LPCTSTR path = L"C:\\sample.txt";
WIN32_FILE_ATTRIBUTE_DATA lpFileInformation;

BOOL succeed = GetFileAttributesEx(
    path,
    GET_FILEEX_INFO_LEVELS::GetFileExInfoStandard,
    &lpFileInformation);
typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
  DWORD    dwFileAttributes; // 属性
  FILETIME ftCreationTime;   // 作成日時
  FILETIME ftLastAccessTime; // アクセス日時
  FILETIME ftLastWriteTime;  // 更新日時
  DWORD    nFileSizeHigh;    // サイズを表す値の上位32ビット
  DWORD    nFileSizeLow;     // サイズを表す値の下位32ビット
} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
WIN32_FILE_ATTRIBUTE_DATA structure (Windows) | MSDN

ディレクトリの作成

BOOL CreateDirectoryW(
  [in]           LPCWSTR               lpPathName,
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
CreateDirectoryW function (fileapi.h) - Win32 apps | Microsoft Learn

すでにディレクトリが存在するならばゼロではない値が返され、GetLastError()で183 (0xB7) ERROR_ALREADY_EXISTSが返されます。

指定のディレクトリまでのパスが存在しないならば、そのサブディレクトリは作成されずに、3 (0x3) ERROR_PATH_NOT_FOUNDが返されます。これを中間フォルダ (intermediate folders) も含めて作成したいならばSHCreateDirectory()を用います。 c++ - How do I recursively create a folder in Win32? - Stack Overflow

SHCreateDirectory()

int SHCreateDirectory(
  [in, optional] HWND   hwnd,
  [in]           PCWSTR pszPath
);
SHCreateDirectory function (shlobj_core.h) - Win32 apps | Microsoft Learn

pszPathは、ディレクトリの完全修飾パス (fully qualified path) で指定します。

戻り値のエラーコードの意味は、strerror()で取得できます。

絶対パスの取得

絶対パスまたはフルパスを取得できます。

char *_fullpath(
  char *absPath,
  const char *relPath,
  size_t maxLength
);
_fullpath, _wfullpath | Microsoft Learn

戻り値はabsPathへのポインタです。relPathに無効なドライブレターが含まれていたり、作成されたabsPathの長さがmaxLengthを超えたりしてエラーが発生したときにはNULLが返されます。

char buffer[_MAX_PATH];
if (_fullpath(buffer, path, _MAX_PATH) == NULL)
{
    // 失敗
}

ディレクトリの変更監視

Obtaining Directory Change Notifications - Win32 apps | Microsoft Learn

HANDLE FindFirstChangeNotificationW(
  LPCWSTR lpPathName,
  BOOL    bWatchSubtree,
  DWORD   dwNotifyFilter
);
FindFirstChangeNotificationW function (fileapi.h) - Win32 apps | Microsoft Learn

dwNotifyFilterには下表の値を指定します。

数値 意味
FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 Any file name change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a file name.
FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.
FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 Any attribute change in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_SIZE 0x00000008 Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_SECURITY 0x00000100 Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.
Parameters - FindFirstChangeNotificationW function (fileapi.h) - Win32 apps | Microsoft Learn
BOOL FindNextChangeNotification(
  HANDLE hChangeHandle
);
FindNextChangeNotification function (fileapi.h) - Win32 apps | Microsoft Learn
BOOL ReadDirectoryChangesW(
  HANDLE                          hDirectory,
  LPVOID                          lpBuffer,
  DWORD                           nBufferLength,
  BOOL                            bWatchSubtree,
  DWORD                           dwNotifyFilter,
  LPDWORD                         lpBytesReturned,
  LPOVERLAPPED                    lpOverlapped,
  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
ReadDirectoryChangesW function (winbase.h) - Win32 apps | Microsoft Learn
Microsoft Learnから検索