ファイル操作2
ファイル操作1ではファイルの操作にハンドルを使用しましたが、このページで紹介する関数はファイル名(ディレクトリ名)で直接操作します。
ファイルの属性
GetFileAttributes関数
ファイルやフォルダには「読み取り専用」や「隠しファイル」などの属性(ファイル属性)があります。
ファイル属性を取得するにはGetFileAttributes
関数を使用します。
- DWORD GetFileAttributesW(
LPCWSTR lpFileName
); - ファイルまたはディレクトリlpFileNameのファイルシステム属性を取得する。
引数はファイル名(ディレクトリ名)です。
(ファイルのハンドルではありません)
戻り値は属性を表す定数の組み合わせです。
特に重要なものは太字で表しています。
関数が失敗した場合はINVALID_FILE_ATTRIBUTES
を返します。
定数 | 説明 |
---|---|
FILE_ATTRIBUTE_READONLY | 読み取り専用 (ファイルのみ) |
FILE_ATTRIBUTE_HIDDEN | 隠しファイルまたはディレクトリ |
FILE_ATTRIBUTE_SYSTEM | システムファイルまたはディレクトリ |
FILE_ATTRIBUTE_DIRECTORY | ディレクトリである |
FILE_ATTRIBUTE_ARCHIVE | アーカイブファイルまたはディレクトリ |
FILE_ATTRIBUTE_DEVICE | システムで予約されている (使用しない) |
FILE_ATTRIBUTE_NORMAL | 通常のファイル (属性なし) このフラグは他のフラグと組み合わせられない |
FILE_ATTRIBUTE_TEMPORARY | 一時ファイル |
FILE_ATTRIBUTE_SPARSE_FILE | スパースファイル |
FILE_ATTRIBUTE_REPARSE_POINT | ファイルまたはディレクトリは再解析ポイント(リパースポイント)に関連付けられている (ジャンクション、シンボリックリンク) |
FILE_ATTRIBUTE_COMPRESSED | 圧縮されたファイルまたはディレクトリ |
FILE_ATTRIBUTE_OFFLINE | すぐに利用できないオフラインファイル この値は変更すべきではない |
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | インデックスサービスの対象になっていないファイルまたはディレクトリ |
FILE_ATTRIBUTE_ENCRYPTED | 暗号化されたファイルまたはディレクトリ |
FILE_ATTRIBUTE_INTEGRITY_STREAM | 整合性のあるディレクトリまたはストリーム (ReFSボリュームのみ。Windows Server 2012以降) |
FILE_ATTRIBUTE_VIRTUAL | システムで予約されている (使用しない) |
FILE_ATTRIBUTE_NO_SCRUB_DATA | スクラブファイルなし属性 (ReFSボリュームのみ。Windows8、Windows Server 2012以降) |
これらの定数の組み合わせが返されるので、特定の属性を持つかどうかはビット演算を使用して判定します。
DWORD attr = GetFileAttributes(L"C:\\a.txt");
if (attr == INVALID_FILE_ATTRIBUTES) {
//属性取得失敗
}
if (attr & FILE_ATTRIBUTE_READONLY) {
//読み取り専用
}
if (!(attr & FILE_ATTRIBUTE_READONLY)) {
//読み取り専用ではない
}
GetFileAttributesEx関数
ファイル属性の取得はGetFileAttributesEx
関数を使用することもできます。
- BOOL GetFileAttributesExW(
LPCWSTR lpFileName,
GET_FILEEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFileInformation
); - ファイルまたはディレクトリlpFileNameのファイルシステム属性を取得しlpFileInformationに格納する。
成功した場合は0以外を、失敗した場合は0を返す。
第二引数fInfoLevelId
にはGetFileExInfoStandard
という定数を指定します。
これは第三引数に格納される値はWIN32_FILE_ATTRIBUTE_DATA
構造体である、という意味です。
(この定数以外を指定することはできません)
第三引数lpFileInformation
はWIN32_FILE_ATTRIBUTE_DATA
構造体です。
- typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; - ファイルやディレクトリに関する情報を格納する構造体。
dwFileAttributes
メンバはファイルの属性です。
これはGetFileAttributes関数と同様です。
ftCreationTime
、ftLastAccessTime
、ftLastWriteTime
メンバはそれぞれ「作成日時」「最終アクセス日時」「更新日時」です。
これはGetFileTime関数で取得されるものと同等です。
nFileSizeHigh
メンバはファイルサイズの上位DWORD、nFileSizeLow
はファイルサイズの下位DWORDです。
これはGetFileSize関数で取得されるものと同等です。
ディレクトリのサイズは取得できません。
GetFileSize関数やGetFileTime関数はファイルハンドルが必要なためファイルのオープンとクローズの処理が必要ですが、GetFileAttributesEx関数はファイル名を指定するだけで情報が取得できます。
WIN32_FILE_ATTRIBUTE_DATA fad;
BOOL b = GetFileAttributesEx(
L"C:\\a.txt",
GetFileExInfoStandard,
&fad);
//ファイル属性
DWORD attr = fad.dwFileAttributes;
SetFileAttributes関数
ファイル属性の設定はSetFileAttributes
関数を使用します。
- BOOL SetFileAttributesW(
LPCWSTR lpFileName,
DWORD dwFileAttributes
); - ファイルまたはディレクトリlpFileNameの属性をdwFileAttributesに設定する。
成功した場合は0以外を、失敗した場合は0を返す。
第二引数に指定する値はGetFileAttributes関数で説明した定数の組み合わせですが、指定できる値は以下のものに制限されています。
- FILE_ATTRIBUTE_READONLY
- FILE_ATTRIBUTE_HIDDEN
- FILE_ATTRIBUTE_SYSTEM
- FILE_ATTRIBUTE_NORMAL
- FILE_ATTRIBUTE_TEMPORARY
- FILE_ATTRIBUTE_OFFLINE
- FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
DWORD attr = GetFileAttributes(L"C:\\a.txt");
//読み取り専用属性を設定
SetFileAttributesW(L"C:\\a.txt", attr | FILE_ATTRIBUTE_READONLY);
attr = GetFileAttributes(L"R:\\a.txt");
//読み取り専用属性を解除
SetFileAttributesW(L"C:\\a.txt", attr & ~FILE_ATTRIBUTE_READONLY);
ファイルの削除
ファイルの削除はDeleteFile
関数を使用します。
- BOOL DeleteFile(
LPCTSTR lpFileName
); - ファイルlpFileNameを削除する。
成功した場合は0以外を、失敗した場合は0を返す。
指定したファイルパスのファイルを削除します。
ファイルが存在しない、読み取り専用、削除権限がない、他のプログラムが使用中、などの場合には関数は失敗します。
また、ごみ箱には移動せず即座に削除されるので注意してください。
ディレクトリの削除にはRemoveDirectory関数を使用します。
ファイルのコピー
ファイルのコピーはCopyFile
関数を使用します。
- BOOL CopyFile(
LPCTSTR lpExistingFileName,
LPCTSTR lpNewFileName,
BOOL bFailIfExists
); - 既存のファイルlpExistingFileNameを新しいファイルlpNewFileNameにコピーする。
成功した場合は0以外を、失敗した場合は0を返す。
第三引数のbFailIfExists
はBOOL値で、コピー先のパスにすでにファイルが存在する場合の動作を決定します。
TRUE
を指定するとファイルの上書きはせず関数は失敗します。
FALSE
を指定するとファイルを上書きします。
ディレクトリをコピーする関数は標準では用意されていません。
(ディレクトリの移動、名前変更、コピーを参照)
ファイルの移動(名前の変更)
ファイルの移動はMoveFile
関数を使用します。
- BOOL MoveFile(
LPCTSTR lpExistingFileName,
LPCTSTR lpNewFileName
); - ファイルまたはディレクトリlpExistingFileNameをlpNewFileNameに移動する。
成功した場合は0以外を、失敗した場合は0を返す。
移動先にすでにファイルが存在する場合は関数は失敗します。
ファイル名を変更する場合もこの関数を使用します。
この関数はディレクトリの移動も可能です。
ただしディレクトリを移動する場合、異なるボリューム(別ドライブ)への移動はできません。
(ディレクトリの移動、名前変更、コピーを参照)
ファイルの存在確認
指定のファイルが存在するかの確認はPathFileExists
関数を使用します。
- BOOL PathFileExistsW(
LPCWSTR pszPath
); - ファイルまたはディレクトリpszPathが存在する場合はTRUEを返す。
存在しない場合はFALSEを返す。
この関数の使用にはShlwapi.h
のインクルードおよびShlwapi.lib
のリンクが必要です。
#pragma comment(lib, "Shlwapi.lib")
#include<Windows.h>
#include<Shlwapi.h>
ファイルの移動やコピーの前に、宛先にファイルが存在するかをチェックする場合に使用できます。
この関数はディレクトリの存在確認も可能です。
ファイルやディレクトリはあらゆるプログラムからアクセスされるため、存在チェックを行った次の瞬間には別のプログラムによって状態が変更されている可能性があるので注意してください。
ファイルとディレクトリの判別
PathFileExists関数は指定のパスが有効なファイルまたはディレクトリの場合にTRUE
を返します。
そのままではファイルとディレクトリを判別できないので、PathIsDirectory
関数を使用して識別します。
この関数の使用にはShlwapi.h
のインクルードおよびShlwapi.lib
のリンクが必要です。
- BOOL PathIsDirectoryW(
LPCWSTR pszPath
); - ディレクトリpszPathが存在する場合はTRUEを返す。
存在しない場合はFALSEを返す。
WCHAR* path = L"test.txt";
if (PathFileExists(path))
{
if (PathIsDirectory(path))
{
//pathはディレクトリ
}
else
{
//pathはファイル
}
}
else
{
//ファイルまたはディレクトリは存在しない
}
その他、GetFileAttributes関数などでファイルの属性を取得して判別することもできます。
DWORD attr = GetFileAttributes(L"C:\\a.txt");
if (attr == INVALID_FILE_ATTRIBUTES) {
//属性取得失敗
}
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
//ディレクトリ
}