C 言語でファイルサイズを取得する

胡金庫 2023年10月12日
  1. 関数 stat を使って C 言語でファイルサイズを取得する
  2. 関数 fstat を用いて C 言語でファイルサイズを取得する
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_modest_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);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C File