C 言語でファイルサイズを取得する
この記事では、C 言語でファイルサイズを取得する方法をいくつか説明します。
関数 stat
を使って C 言語でファイルサイズを取得する
stat
システムコールは POSIX に準拠した関数であり、与えられたファイルの様々な属性を取得するために利用することができます。第 1 引数はファイルのパス名を指す char
ポインタであり、第 2 引数は関数マニュアルで幅広く説明されている struct stat
ポインタの型です。関数呼び出しが成功すると、ユーザは struct stat
のメンバに直接アクセスすることで、ファイルの必要な属性を struct stat
から抽出することができます。ファイルサイズは構造体の st_size
メンバに格納されます。なお、stat
関数は属性を取得するためにファイルのパーミッションを必要としないが、パス名に含まれる全てのディレクトリに対して呼び出し元が実行権限を持っていなければならないことに注意してください。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
const char *filename = "input.txt";
int main(int argc, char *argv[]) {
struct stat sb;
if (stat(filename, &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
printf("Inode number: %lu\n", sb.st_ino);
printf("User ID of owner: %u\n", sb.st_uid);
printf("Group ID of owner: %u\n", sb.st_gid);
printf("Total file size: %lu bytes\n", sb.st_size);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS);
}
出力:
Inode number: 12638061
User ID of owner: 1000
Group ID of owner: 1000
Total file size: 126 bytes
Last status change: Sat Feb 6 23:35:02 2021
Last file access: Sat Feb 6 23:35:02 2021
Last file modification: Sat Feb 6 23:35:02 2021
メンバ st_size
はファイルの総サイズをバイト単位で表します。与えられたパス名がシンボリックリンクの場合、このメンバはそのリンクによるパス名ポインタの長さを示します。以下の例では、ユーザがプログラムのパラメータとしてファイル名を渡しても構わないが、上のコードサンプルで宣言した const
のハードコード化された文字列の値からファイル名を取得する例を実装します。stat
コールは失敗した場合は -1
を返し、それに応じて errno
が設定されます; それ以外の場合は成功を示すためにゼロが返されます。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
int main(int argc, char *argv[]) {
struct stat sb;
char *filename = NULL;
if (argc != 2) {
printf("Usage: ./program filename\n");
exit(EXIT_FAILURE);
}
filename = argv[1];
if (stat(filename, &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
printf("Inode number: %lu\n", sb.st_ino);
printf("User ID of owner: %u\n", sb.st_uid);
printf("Group ID of owner: %u\n", sb.st_gid);
printf("Total file size: %lu bytes\n", sb.st_size);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS);
}
関数 fstat
を用いて C 言語でファイルサイズを取得する
あるいは、fstat
関数を利用することもできます。これはファイルディスクリプタを第一引数に取り、対象のファイルを指定します。ファイルディスクリプタは open
システムコールで取得することができるが、不要になったら close
システムコールで閉じるようにしてほしい。この記事のすべての例では、struct stat
のメンバのほとんどが表示されていることに注意してほしい。追加の関数、例えば st_mode
や st_dev
などを使って、属性に関する関連情報を抽出する必要があるかもしれません。
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
const char *filename = "input.txt";
int main(int argc, char *argv[]) {
struct stat sb;
int fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
if (fstat(fd, &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
printf("Inode number: %lu\n", sb.st_ino);
printf("User ID of owner: %u\n", sb.st_uid);
printf("Group ID of owner: %u\n", sb.st_gid);
printf("Total file size: %lu bytes\n", sb.st_size);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
close(fd);
exit(EXIT_SUCCESS);
}