[C言語] ファイルの作成日時・更新日時を取得する
C言語でファイルの作成日時や更新日時を取得するには、stat構造体を使用します。
この構造体はsys/stat.hヘッダーファイルに定義されており、stat関数を用いてファイルのメタデータを取得できます。
取得したstat構造体のメンバーであるst_ctimeはファイルの状態が最後に変更された時間を、st_mtimeはファイルの内容が最後に変更された時間を示します。
これらの時間はtime_t型で表され、ctime関数を使って可読な形式に変換できます。
ファイルの作成日時・更新日時を取得する方法
ファイルの作成日時や更新日時を取得することは、ファイル管理やバックアップシステムの構築において重要です。
C言語では、プラットフォームに応じた方法でこれらの情報を取得することができます。
以下では、POSIX標準、Windows API、そしてクロスプラットフォームでの対応方法について解説します。
POSIX標準の利用
POSIX標準では、stat関数を使用してファイルのメタデータを取得することができます。
この関数は、ファイルのパスを指定して呼び出し、stat構造体に情報を格納します。
stat構造体には、ファイルの作成日時や更新日時が含まれています。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
struct stat fileStat;
if(stat("example.txt", &fileStat) < 0) {
perror("stat error");
return 1;
}
printf("ファイルの更新日時: %ld\n", fileStat.st_mtime);
return 0;
}ファイルの更新日時: 1633036800この例では、example.txtというファイルの更新日時を取得しています。
st_mtimeは、ファイルの最終更新時刻を表すメンバーです。
Windows APIの利用
Windows環境では、GetFileTime関数を使用してファイルの作成日時や更新日時を取得できます。
この関数は、ファイルハンドルを使用してファイルの時間情報を取得し、FILETIME構造体に格納します。
#include <windows.h>
#include <stdio.h>
int main() {
HANDLE hFile = CreateFile("example.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("ファイルを開けません\n");
return 1;
}
FILETIME creationTime, lastAccessTime, lastWriteTime;
if (GetFileTime(hFile, &creationTime, &lastAccessTime, &lastWriteTime)) {
printf("ファイルの作成日時を取得しました\n");
} else {
printf("ファイルの作成日時を取得できません\n");
}
CloseHandle(hFile);
return 0;
}ファイルの作成日時を取得しましたこのコードは、example.txtの作成日時を取得し、成功した場合にメッセージを表示します。
クロスプラットフォームでの対応
クロスプラットフォームでファイルの作成日時や更新日時を取得するには、条件付きコンパイルを利用して、プラットフォームごとに異なるコードを実行する方法があります。
#ifdefディレクティブを使用して、OSに応じたコードを選択します。
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
void getFileTime() {
// Windows用のコード
printf("Windows用のファイル時間取得\n");
}
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void getFileTime() {
// POSIX用のコード
printf("POSIX用のファイル時間取得\n");
}
#endif
int main() {
getFileTime();
return 0;
}POSIX用のファイル時間取得このコードは、コンパイル時にプラットフォームを判別し、適切なファイル時間取得方法を選択します。
これにより、同じコードベースで異なるプラットフォームに対応することが可能です。
POSIX標準を用いた実装
POSIX標準を用いることで、Unix系システム上でファイルの作成日時や更新日時を取得することができます。
ここでは、stat構造体を利用した実装方法について詳しく解説します。
stat構造体の利用
stat構造体は、ファイルのメタデータを格納するための構造体で、stat関数を使用してファイルの情報を取得します。
この構造体には、ファイルのサイズ、アクセス権、作成日時、更新日時などの情報が含まれています。
| メンバー名 | 説明 |
|---|---|
| st_dev | デバイスID |
| st_ino | iノード番号 |
| st_mode | ファイルの種類とアクセス権 |
| st_nlink | ハードリンクの数 |
| st_uid | 所有者のユーザーID |
| st_gid | 所有者のグループID |
| st_size | ファイルサイズ(バイト単位) |
| st_atime | 最終アクセス時刻 |
| st_mtime | 最終修正時刻 |
| st_ctime | 状態変更時刻 |
サンプルコードの解説
以下に、stat構造体を用いてファイルの更新日時を取得するサンプルコードを示します。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
struct stat fileStat;
if(stat("example.txt", &fileStat) < 0) {
perror("stat error");
return 1;
}
printf("ファイルの更新日時: %ld\n", fileStat.st_mtime);
return 0;
}このコードでは、stat関数を使用してexample.txtの情報を取得し、fileStat構造体に格納しています。
st_mtimeメンバーを使用して、ファイルの最終更新時刻を取得し、表示しています。
ファイルの更新日時: 1633036800この出力は、UNIX時間(1970年1月1日からの秒数)で表示されます。
必要に応じて、localtime関数などを使用して人間が読みやすい形式に変換することができます。
エラーハンドリングの実装
stat関数の呼び出しが失敗した場合、エラーハンドリングを行うことが重要です。
stat関数は、失敗した場合に-1を返し、errnoにエラーコードを設定します。
perror関数を使用して、エラーメッセージを表示することができます。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
int main() {
struct stat fileStat;
if(stat("example.txt", &fileStat) < 0) {
perror("stat error");
return 1;
}
printf("ファイルの更新日時: %ld\n", fileStat.st_mtime);
return 0;
}このコードでは、stat関数が失敗した場合にperrorを使用してエラーメッセージを表示し、プログラムを終了します。
これにより、ファイルが存在しない場合やアクセス権がない場合に適切なエラーメッセージを表示することができます。
Windows APIを用いた実装
Windows環境では、ファイルの作成日時や更新日時を取得するためにWindows APIを利用します。
ここでは、GetFileTime関数とFILETIME構造体を用いた実装方法について詳しく解説します。
GetFileTime関数の利用
GetFileTime関数は、指定したファイルの作成日時、最終アクセス日時、最終更新日時を取得するための関数です。
この関数は、ファイルハンドルを使用してファイルの時間情報を取得し、それぞれのFILETIME構造体に格納します。
| パラメータ | 説明 |
|---|---|
| hFile | ファイルハンドル |
| lpCreationTime | 作成日時を受け取るFILETIME構造体へのポインタ |
| lpLastAccessTime | 最終アクセス日時を受け取るFILETIME構造体へのポインタ |
| lpLastWriteTime | 最終更新日時を受け取るFILETIME構造体へのポインタ |
FILETIME構造体の理解
FILETIME構造体は、64ビットの値でファイルの時間を表現します。
この値は、1601年1月1日からの100ナノ秒間隔の数を示しています。
FILETIME構造体を人間が読みやすい形式に変換するためには、FileTimeToSystemTime関数を使用します。
| メンバー名 | 説明 |
|---|---|
| dwLowDateTime | 低位32ビット |
| dwHighDateTime | 高位32ビット |
サンプルコードの解説
以下に、GetFileTime関数を用いてファイルの作成日時を取得するサンプルコードを示します。
#include <windows.h>
#include <stdio.h>
void printFileTime(const FILETIME *ft) {
SYSTEMTIME st;
FileTimeToSystemTime(ft, &st);
printf("%d/%d/%d %d:%d:%d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
}
int main() {
HANDLE hFile = CreateFile("example.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("ファイルを開けません\n");
return 1;
}
FILETIME creationTime, lastAccessTime, lastWriteTime;
if (GetFileTime(hFile, &creationTime, &lastAccessTime, &lastWriteTime)) {
printf("ファイルの作成日時: ");
printFileTime(&creationTime);
} else {
printf("ファイルの作成日時を取得できません\n");
}
CloseHandle(hFile);
return 0;
}このコードでは、CreateFile関数を使用してファイルハンドルを取得し、GetFileTime関数でファイルの作成日時を取得しています。
printFileTime関数を用いて、FILETIME構造体を人間が読みやすい形式に変換して表示しています。
ファイルの作成日時: 2023/10/1 12:34:56この出力は、example.txtの作成日時を年/月/日 時:分:秒の形式で表示しています。
GetFileTime関数が成功した場合にのみ、日時が表示されます。
応用例
ファイルの作成日時や更新日時を取得する技術は、さまざまな応用が可能です。
ここでは、具体的な応用例として、ファイルのバックアップシステムの構築、ファイルの変更履歴管理、自動化スクリプトでの活用について解説します。
ファイルのバックアップシステムの構築
ファイルの更新日時を利用することで、バックアップシステムを効率的に構築することができます。
更新日時をチェックし、変更があったファイルのみをバックアップすることで、無駄なデータ転送を減らし、バックアップの速度を向上させることができます。
- 差分バックアップ: 更新日時を基に、前回のバックアップ以降に変更されたファイルのみをバックアップします。
- 増分バックアップ: 最初のフルバックアップ以降に変更されたファイルをすべてバックアップします。
これにより、ストレージの使用量を抑えつつ、重要なデータを確実に保護することが可能です。
ファイルの変更履歴管理
ファイルの作成日時や更新日時を記録することで、ファイルの変更履歴を管理することができます。
これにより、特定の時点でのファイルの状態を確認したり、変更の追跡を行ったりすることが可能です。
- バージョン管理: 各ファイルの更新日時を記録し、異なるバージョンのファイルを保存します。
- 変更ログの作成: ファイルが変更された際に、更新日時とともに変更内容をログに記録します。
このような履歴管理は、開発プロジェクトやドキュメント管理において非常に有用です。
自動化スクリプトでの活用
ファイルの作成日時や更新日時を利用して、自動化スクリプトを作成することができます。
これにより、特定の条件に基づいてファイル操作を自動化し、作業効率を向上させることができます。
- 定期的なファイル整理: 更新日時を基に、古いファイルを自動的にアーカイブまたは削除します。
- 同期スクリプト: 更新日時をチェックし、ローカルとリモートのファイルを同期します。
このような自動化スクリプトは、日常的なファイル管理の手間を大幅に削減し、作業の効率化に貢献します。
まとめ
ファイルの作成日時や更新日時を取得する方法は、C言語を用いてさまざまなプラットフォームで実装可能です。
POSIX標準やWindows APIを利用することで、効率的なファイル管理やバックアップシステムの構築が可能になります。
この記事を参考に、実際のプロジェクトでこれらの技術を活用してみてください。