ファイルサイズの取得

ファイル処理7

ファイルサイズを取得するにはstat関数を使用します。
stat関数を使用するためにはstat構造体も使用します。

#include <stdio.h>
#include <sys/stat.h>

void Write(const char *file)
{
    FILE *fp;

    //fp = fopen(file, "w");
    fopen_s(&fp, file, "w");
    if (fp == NULL)
    {
        printf("%sのオープンに失敗しました。\n", file);
        return;
    }

    char str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\
abcdefghijklmnopqrstuvwxyz";

    fputs(str, fp);

    fclose(fp);

    printf("%sに保存しました。\n", file);
}

//ファイルサイズを取得する
//戻り値が-1の場合は取得失敗
long GetFileSize(const char *file)
{
    struct stat statBuf;

    if (stat(file, &statBuf) == 0)
        return statBuf.st_size;

    return -1L;
}


int main()
{
    const char *file = "C:\\test.txt";
    long size;

    Write(file);
    size = GetFileSize(file);

    printf("%sのサイズ: %d", file, size);

    getchar();
}

stat関数の使用には#include <sys/stat.h>が必要です。

ファイルは「ABC~XYZ(改行)abc~xyz」というテキストを用意しています。
(別にどんなファイルでも構いません)
コードが横に長くなりすぎるので、途中でコードを分割しています。
(16、17行目。\記号に続いて改行でコードを改行できる)

stat構造体とstat関数

int stat(
 const char *path,
 struct stat *buffer
);
文字列pathに存在するファイルから情報を取得し、stat構造体変数bufferに格納する。
戻り値は関数が成功した場合は0を、失敗した場合は-1を返す。

stat構造体はファイルに関する各種情報を持つ構造体です。
ファイルサイズのほか、ファイルへのアクセス日時や修正日時なども保存されています。
ファイルサイズは「st_size」というメンバ変数(long型)に保存されます。

stat関数は指定したファイルの情報をstat構造体の変数に値を格納する関数です。
stat構造体の変数はポインタで渡します。

stat関数は成功すると0を返すので、関数が成功した場合にstat構造体のメンバ変数st_sizeの値を返します。
(32、33行目)

アルファベット26文字+26文字と、改行コード(Windowsのテキストモードでは2文字)のテキストファイルですから、54バイトが取得できているはずです。
UNIX系のOS(MacOS、Linux)ならば1バイト少ない53バイトです。

C:¥test.txtに保存しました。
C:¥test.txtのサイズ: 54

fseek関数とftell関数によるファイルサイズ取得

ファイルサイズの取得には、fseek関数とftell関数を利用した方法もあります。
fseek関数でファイルの終わりにファイル位置指示子をセットし、ftell関数でファイルの位置を取得すれば、それはファイルサイズを示している、というわけです。
(fseek関数とftell関数に関してはランダムアクセスを参照)

しかしこの方法は推奨されません。

まず、ファイルをバイナリモードで開いた時、fseek関数の第三引数(origin)に「SEEK_END」を指定することはできません。
これがどのような動作をするのかは未定義です。

テキストモードでは「SEEK_END」を使用できますが、ftell関数の戻り値はfseek関数の呼び出しに使用する以外の方法は想定されていません。
ファイル位置がファイルの終端を指していても、ftell関数の戻り値は正しくファイルサイズを示しているとは限らないのです。

確実にファイルサイズを取得するならば、stat関数を利用すべきです。
(C言語の機能にこだわらないなら、OSが提供するAPIを使った方が確実です)