GetFileAttributesとSetFileAttributesでファイル属性を操作する
Windowsのファイル属性は、ファイルの表示方法、書き込み条件、暗号化状態などを OS 側で管理するためのメタデータです。GetFileAttributes と SetFileAttributes は、それぞれ属性の取得と変更担当し、Windows API によるファイル管理の基本となります。
属性値はビットフラグとして返るため、単純な真偽判定だけでは扱えません。また、属性変更にはアクセス権限やファイルシステム固有の制約があり、読み取り専用属性とアクセス制御 likewise 混同しないことが重要です。
| 観点 | GetFileAttributes | SetFileAttributes |
|---|---|---|
| 主な目的 | パス指定で属性を取得する | パス指定で属性を設定する |
| 入力 | ファイルまたはディレクトリのパス | 変更後の属性ビット |
| 戻り値 | 属性ビット、または INVALID_FILE_ATTRIBUTES |
成功時は真、失敗時は偽 |
| 失敗時の確認 | 直ちに GetLastError を呼ぶ |
直ちに GetLastError を呼ぶ |
| 変更方式 | 既存状態を変更しない | 指定した属性一式で置き換える |
| 主な制約 | パスと権限が必要 | 権限、共有状態、ファイルシステムが必要 |
属性ビットの意味
GetFileAttributes が返す値は、FILE_ATTRIBUTE_READONLY、FILE_ATTRIBUTE_HIDDEN、FILE_ATTRIBUTE_SYSTEM、FILE_ATTRIBUTE_ARCHIVE などのビット combinations です。複数の属性が同時に立つ場合があるため、それぞれの有無はビット AND 演算で判定します。
FILE_ATTRIBUTE_DIRECTORY は対象がディレクトリであることを示します。FILE_ATTRIBUTE_NORMAL は他の属性が設定されていない状態を表し、通常は単独で使用します。アーカイブ、一時、スパース、圧縮、暗号化などの属性は、ファイルシステムの機能によって意味や変更可否が異なります。
読み取り専用属性はファイル内容の読み取りを禁止する属性ではありません。内容の読み書きは ReadFile や WriteFile などの関数制御であり、ReadFileとWriteFileの注意点 .Extension と併用して理解する必要があります。
属性取得の戻り値を検証する
GetFileAttributesW は UTF-16 文字列でパスを받으며、成功時に属性ビットを返します。失敗の標識は INVALID_FILE_ATTRIBUTES で、0 との比較では不十分です。
DWORD attributes = GetFileAttributesW(L"C:\\Data\\report.txt");
if (attributes == INVALID_FILE_ATTRIBUTES) {
DWORD error = GetLastError();
// 記録または例外処理へ渡す
return false;
}
bool isDirectory =
(attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
bool isReadOnly =
(attributes & FILE_ATTRIBUTE_READONLY) != 0;
失敗を検出した直後に GetLastError を呼び、記録します。その間に別の API を実行するとエラーコードが上書きされ、原因の特定が難しくなるためです。
パスの形式も確認事項です。日本語や補助平面の文字を含む場合は GetFileAttributesW を使い、UNC パスや長いパスでは、パス形式と前方スラッシュの扱いを環境に合わせて検証します。
属性を設定する手順
SetFileAttributesW は、指定した属性ビットで対象の状態を設定します。個別属性を切り替える API ではないため、既存の値を取得してから変更する形が基本です。
DWORD attributes = GetFileAttributesW(path);
if (attributes == INVALID_FILE_ATTRIBUTES) {
return false;
}
DWORD updated = attributes & ~FILE_ATTRIBUTE_READONLY;
updated |= FILE_ATTRIBUTE_HIDDEN;
if (!SetFileAttributesW(path, updated)) {
DWORD error = GetLastError();
return false;
}
この例では読み取り専用ビットだけを取り除き、隠し属性を追加しています。属性を完全に消去目的とするなら FILE_ATTRIBUTE_NORMAL を単独で指定できますが、任意のビットを自由に組み合わせられるわけではありません。
取得と設定の間で別処理が属性を変える可能性には注意が必要です。識別性を厳密に保つ必要があれば、パス操作ではなくハンドル基準の GetFileInformationByHandle や SetFileInformationByHandle を検討します。
失敗要因と保護的区别
失敗の代表例には、パスの不存在、アクセス拒否、ロックまたは共有状態との競合、ファイルシステムの未対応があります。ネットワーク共有では、サーバー側の権限やポリシーによって operatingsystem ローカルと結果が異なることもあります。
ファイル属性と ACL は別々の保護機構です。読み取り専用属性を解除しても、ACL が書き込みを拒否していれば変更できません。逆に、属性変更権限があってもアプリケーションがファイルを開いている場合は、共有モードによって操作が失敗することがあります。
また、属性ビットはファイル内容を暗号化する機能ではありません。通信や保存データの保護には、SSL暗号化の概要 などで扱う暗号化が別途必要です。属性による表示制御と、内容そのものの保護を混同しないことが重要です。
実装で押さえる安全性
安全な実装では、取得・判定・変更・検証を一連の流れとして扱います。特に、失敗判定とエラー取得は省略せず、変更対象がファイルかディレクトリかも区別します。
- 属性取得後は必ず
INVALID_FILE_ATTRIBUTESと比較し、直ちにGetLastErrorを取得する - 日本語を含むパスには
GetFileAttributesWとSetFileAttributesWを使用する - 属性を変更するときは変更後のビット一式を組み立て、既存属性を不用意に消さない
- 排他要件が厳しい処理では、パス再解決による識別子の取り違えを避ける
- アクセス制御と属性変更を分け、権限不足を属性変更だけで解決しないと判断する
- 実ファイルと隣接するテスト用ディレクトリで、想定しない属性継承や失敗を確認する
監視や自動化に組み込む場合は、対象パス、実行時刻、变更前后的属性、エラーコードを記録すると原因追及が容易になります。仕様確認や関連実装の比較には、API情報の参照先 を:WX 活用できます。
既存環境へ適用する
既存の業務へ導入する段階では、まず変更対象を限定し、原本ではなく複製ファイルをテスト材料にします。属性変更の前後で値を取得し、想定どおりか、復元可能か、監査ログに残すかを確認します。
権限や共有条件の違いを補うため、管理者権限での実行と通常の実行権限での実行を分けて検証します。変更が失敗した場合でも、元の属性ビットを保存しておけば、同じ手順で復元できます。ネットワークドライブや特殊なボリュームは、another ローカル環境とは異なる扱いになるため対象外に含めるか、別の試験領域を用意します。
次の手順では、C:\Data\report.txt を複製したテストファイルで、読み取り専用解除、隠し属性の設定、取得結果の検証、元属性への復元を一連で実行し、各 API の戻り値とエラーコードをログへ残してください。