[C言語] ファイルの作成日時・更新日時を取得する

C言語でファイルの作成日時や更新日時を取得するには、stat構造体を使用します。

この構造体はsys/stat.hヘッダーファイルに定義されており、stat関数を用いてファイルのメタデータを取得できます。

取得したstat構造体のメンバーであるst_ctimeはファイルの状態が最後に変更された時間を、st_mtimeはファイルの内容が最後に変更された時間を示します。

これらの時間はtime_t型で表され、ctime関数を使って可読な形式に変換できます。

この記事でわかること
  • POSIX標準を用いたファイル日時の取得方法
  • Windows APIを用いたファイル日時の取得方法
  • クロスプラットフォームでの実装方法
  • ファイル管理における応用例

目次から探す

ファイルの作成日時・更新日時を取得する方法

ファイルの作成日時や更新日時を取得することは、ファイル管理やバックアップシステムの構築において重要です。

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_inoiノード番号
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関数が成功した場合にのみ、日時が表示されます。

応用例

ファイルの作成日時や更新日時を取得する技術は、さまざまな応用が可能です。

ここでは、具体的な応用例として、ファイルのバックアップシステムの構築、ファイルの変更履歴管理、自動化スクリプトでの活用について解説します。

ファイルのバックアップシステムの構築

ファイルの更新日時を利用することで、バックアップシステムを効率的に構築することができます。

更新日時をチェックし、変更があったファイルのみをバックアップすることで、無駄なデータ転送を減らし、バックアップの速度を向上させることができます。

  • 差分バックアップ: 更新日時を基に、前回のバックアップ以降に変更されたファイルのみをバックアップします。
  • 増分バックアップ: 最初のフルバックアップ以降に変更されたファイルをすべてバックアップします。

これにより、ストレージの使用量を抑えつつ、重要なデータを確実に保護することが可能です。

ファイルの変更履歴管理

ファイルの作成日時や更新日時を記録することで、ファイルの変更履歴を管理することができます。

これにより、特定の時点でのファイルの状態を確認したり、変更の追跡を行ったりすることが可能です。

  • バージョン管理: 各ファイルの更新日時を記録し、異なるバージョンのファイルを保存します。
  • 変更ログの作成: ファイルが変更された際に、更新日時とともに変更内容をログに記録します。

このような履歴管理は、開発プロジェクトやドキュメント管理において非常に有用です。

自動化スクリプトでの活用

ファイルの作成日時や更新日時を利用して、自動化スクリプトを作成することができます。

これにより、特定の条件に基づいてファイル操作を自動化し、作業効率を向上させることができます。

  • 定期的なファイル整理: 更新日時を基に、古いファイルを自動的にアーカイブまたは削除します。
  • 同期スクリプト: 更新日時をチェックし、ローカルとリモートのファイルを同期します。

このような自動化スクリプトは、日常的なファイル管理の手間を大幅に削減し、作業の効率化に貢献します。

よくある質問

ファイルの作成日時と更新日時は常に取得できるのか?

ファイルの作成日時と更新日時は、通常のファイルシステム上では取得可能ですが、いくつかの例外があります。

例えば、ファイルシステムがこれらの情報をサポートしていない場合や、ファイルに対する適切なアクセス権がない場合には、取得できないことがあります。

例:stat関数が失敗した場合、errnoにエラーコードが設定されます。

クロスプラットフォームでの実装は難しい?

クロスプラットフォームでの実装は、各プラットフォームのAPIや標準ライブラリの違いを理解する必要があるため、多少の難易度があります。

しかし、条件付きコンパイルを利用することで、同じコードベースで異なるプラットフォームに対応することが可能です。

#ifdefディレクティブを使用して、OSに応じたコードを選択することが一般的です。

他のプログラミング言語でも同様のことができる?

はい、他の多くのプログラミング言語でもファイルの作成日時や更新日時を取得することができます。

例えば、Pythonではosモジュールを使用し、Javaではjava.nio.fileパッケージを使用して同様の情報を取得できます。

これにより、C言語以外の環境でもファイル管理を行うことが可能です。

まとめ

ファイルの作成日時や更新日時を取得する方法は、C言語を用いてさまざまなプラットフォームで実装可能です。

POSIX標準やWindows APIを利用することで、効率的なファイル管理やバックアップシステムの構築が可能になります。

この記事を参考に、実際のプロジェクトでこれらの技術を活用してみてください。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • URLをコピーしました!
目次から探す