C言語にはファイルサイズを取得する標準ライブラリ関数がありません。 いろいろな実装方法がありますがその1つを紹介します。


C言語にはファイルサイズを取得する標準関数がない

C言語には、標準ライブラリにてさまざまなファイル操作関数が提供されています。ですが、ファイルサイズを取得する標準関数はありません。 そのため、ファイルサイズを取得するには自分でコードを実装する必要があります。 一般的に使われているfseek()関数を使った実装で事足りますが、これは厳密にはC言語規格に適合していません。 そこで今回は、POSIXを利用してC言語規格に適合したファイルサイズ取得関数を紹介いたします。

C言語規格に適合したファイルサイズ取得方法

fstat() 関数を使用した例を示します。Linuxはもちろん、MSYS2@Windowsでも動作します

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define ERR_PRINTF_EXIT(...) do { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } while(0)

/**
 * @brief ファイルサイズ取得. Windows / Linux 両対応, のはず.
 * @param[in] in_fname ファイル名の文字列
 * @retval ファイルサイズ
 */
static long get_read_file_size(const char *in_fname)
{
    FILE *fp;
    long file_size;
    struct stat stbuf;
    int fd;

    fd = open(in_fname, O_RDONLY);
    if (fd == -1)
        ERR_PRINTF_EXIT("cant open file : %s.\n", in_fname);

    fp = fdopen(fd, "rb");
    if (fp == NULL)
        ERR_PRINTF_EXIT("cant open file : %s.\n", in_fname);

    if (fstat(fd, &stbuf) == -1)
        ERR_PRINTF_EXIT("cant get file state : %s.\n", in_fname);

    file_size = stbuf.st_size;

    if (fclose(fp) != 0)
        ERR_PRINTF_EXIT("cant close file : %s.\n", in_fname);

    return file_size;
}

fseek()関数を使っても、まずちゃんと動くのですが、さらにコードの可搬性を求めるなら、今回紹介した実装の方が良いでしょう。 ぜひご活用ください!

Note

上記の関数はJCERT CCを参考にしました。