2012-01-11 3 views
0
int filesize(FILE * handle) 
{ 
    int filesize; 
    int old_pointer = ftell(handle); 
    fseek(handle, 0, SEEK_END); 
    filesize = ftell(handle); 
    fseek(handle, old_pointer, SEEK_SET); 
    return filesize; 
} 

これは、関数がファイルのサイズを返すための良い方法ですか?ファイルサイズを返す関数?

答えて

2

ファイルが大きすぎない(32ビットシステムまたはWindows 64ビットの場合、2 GiB以下を意味する)限り、これを実行する方法の1つです。どのプラットフォームでも多かれ少なかれ機能するメリットがあります。もちろん、ftell()は、intではなく、longを返します(64ビットWindows以外のシステムでは、コードを適切に修正する限り、報告できるファイルは非常に大きくなります)。しかし、4つの関数呼び出しを必要とするのはちょっと高価です。

POSIXの代替品は、stat(),lstat()およびfstat()です。

Windows APIにはアナログがあります。

+0

より良いPOSIXの代替手段は 'fseeko'と' ftello'です。 'stat'ファミリを使うと、ブロックデバイスや他の普通でないファイルのサイズが正しく取得されません。 –

+0

そして、ターミナルやパイプを探すことはできません。すべてに制限があります。 –

+0

ファイルにサイズがない場合は、サイズを確認することは意味のある操作ではありません。私のアプローチは、答えが存在するときは常に正解を返す。 –

0

* nixの場合は、stat()またはfstat()を使用できます。

0

使用stat

#include <sys/stat.h> 

int stat(const char *path, struct stat *buf); 

struct stat { 
      dev_t  st_dev;  /* ID of device containing file */ 
      ino_t  st_ino;  /* inode number */ 
      mode_t st_mode; /* protection */ 
      nlink_t st_nlink; /* number of hard links */ 
      uid_t  st_uid;  /* user ID of owner */ 
      gid_t  st_gid;  /* group ID of owner */ 
      dev_t  st_rdev; /* device ID (if special file) */ 
--->  off_t  st_size; /* total size, in bytes */ 
      blksize_t st_blksize; /* blocksize for file system I/O */ 
      blkcnt_t st_blocks; /* number of 512B blocks allocated */ 
      time_t st_atime; /* time of last access */ 
      time_t st_mtime; /* time of last modification */ 
      time_t st_ctime; /* time of last status change */ 
}; 
1

私は個人的にそうように、stat家族からの機能を使用すると思います。また、intが戻り値(特に32ビットシステム)には小さすぎる可能性があります。 off_tが動作することが保証されています。

off_t filesize(FILE *handle) { 
    struct stat statbuf; 
    if (fstat(fileno(handle), &statbuf) != 0) { 
     // handle an error 
    } else { 
     return statbuf.st_size; 
    } 
} 

も注意してください、これは簡単に標準stat()代わりのfstat()を使用して、まだ開いていないファイルのために働くために微調整することができます。