C/C++ でファイルサイズ取得
C/C++ を使用して、ファイルサイズを取得する方法の備忘録。
// g++ getFileSize.cpp -lboost_system-mt -lboost_filesystem-mt #define CAN_CUST_FPOS_TO_LONG 0 #include <stdio.h> #if CAN_CUST_FPOS_TO_LONG unsigend long getFileSize1(const char *fileName) { fpos_t fsize; FILE *fp = fopen(fileName, "rb"); fseek(fp, 0, SEEK_END); fgetpos(fp, &fsize); fclose(fp); return (unsigend long) fsize; } #endif #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> unsigned long getFileSize2(const char *fileName) { int fd = open(fileName, O_RDONLY); struct stat statBuf; fstat(fd, &statBuf); close(fd); return (unsigned long) statBuf.st_size; } #include <boost/filesystem.hpp> unsigned long getFileSize3(const char *fileName) { const boost::filesystem::path path(fileName); const boost::uintmax_t size = boost::filesystem::file_size(path); return (unsigned long) size; } int main(int argc, char *argv[]) { #if CAN_CUST_FPOS_TO_LONG unsigned long size1 = getFileSize1("getFileSize.cpp"); #else unsigned long size1 = 0; #endif unsigned long size2 = getFileSize2("getFileSize.cpp"); unsigned long size3 = getFileSize3("getFileSize.cpp"); printf("%ld\n", size1); printf("%ld\n", size2); printf("%ld\n", size3); return 0; }
getFileSize1 は ANSI C で実装可能なんだけど、処理系によって fpos_t の型がまちまちなので、この方法はあまりよろしくない。1 バイトずつシークして数える方法もあるにはあるけど、考えただけでも遅そうなので却下。
getFileSize2 は POSIX な環境なら割と良い方法だと思う。st_size の型がなにかというのがいまいちはっきりしないんだけど、多分 long にキャスト可能。
getFileSize3 は boost を使用するポータブルな方法。Windows でもそのまま動かせるのが強み。C++ が必須になるのと、boost を導入しなければならないのがデメリット。boost::uintmax_t は環境によって uint32_t、uint64_t、unsigned long、unsigned __int64 などと異なる。簡単のためにキャストしているが、実際にはそのままこの型を使えば良いと思う。
この例では省略してるけど、 1 は fp が NULL に、2 は fd が -1 に、3 は boost::filesystem::filesystem_error が throw される可能性があるので、それぞれエラーチェックを行う必要がある。