ファイルのサイズをバイト単位で把握するにはどうすればよいですか?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
Unixライクなシステムでは、POSIXシステムコールを使用できます:stat
パス上、またはfstat
すでに開いているファイル記述子(POSIXのマニュアルページ、Linuxのマニュアルページ)。( 、またはstdioストリーム
からファイル記述子を取得します)。open(2)
fileno(FILE*)
NilObjectのコードに基づく:
#include <sys/stat.h>
#include <sys/types.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
return -1;
}
変更点:
const char
。struct stat
変数名が欠落していた定義を修正しました。-1
の代わりにエラーを返します0
。これは、空のファイルではあいまいになります。off_t
は符号付きタイプなので、これが可能です。エラー時にメッセージを出力する場合fsize()
は、次を使用できます。
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
off_t fsize(const char *filename) {
struct stat st;
if (stat(filename, &st) == 0)
return st.st_size;
fprintf(stderr, "Cannot determine size of %s: %s\n",
filename, strerror(errno));
return -1;
}
32ビットシステムでは、オプションを使用してこれをコンパイルする必要があります-D_FILE_OFFSET_BITS=64
。そうしないと、off_t
最大2GBの値しか保持されません。詳細については、Linuxでのラージファイルサポートの「LFSの使用」セクションを参照してください。
使用しないでくださいint
。最近の汚れとして、サイズが2ギガバイトを超えるファイルが一般的です。
使用しないでくださいunsigned int
。サイズが4ギガバイトを超えるファイルは、少し一般的ではない汚れとして一般的です。
IIRCは、標準ライブラリoff_t
で符号なし64ビット整数として定義されています。これは誰もが使用する必要があるものです。16エクサバイトのファイルがぶらぶらし始めたら、数年で128ビットに再定義できます。
Windowsを使用している場合は、GetFileSizeExを使用する必要があります。実際には符号付き64ビット整数を使用するため、8エクサバイトのファイルで問題が発生し始めます。愚かなマイクロソフト!:-)
Mattのソリューションは、CではなくC ++であり、最初の通知は必要ないことを除いて、機能するはずです。
unsigned long fsize(char* file)
{
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
unsigned long len = (unsigned long)ftell(f);
fclose(f);
return len;
}
中かっこも修正しました。;)
更新:これは実際には最善の解決策ではありません。Windowsでは4GBのファイルに制限されており、GetFileSizeEx
またはのようなプラットフォーム固有の呼び出しを使用するよりも遅くなる可能性がありますstat64
。
**これを行わないでください(なぜですか?):
オンラインで見つけたC99標準ドキュメントの引用:「ファイル位置インジケーターをファイルの終わりに設定すると
fseek(file, 0, SEEK_END)
、バイナリストリーム(末尾にヌル文字が含まれる可能性があるため)または状態に依存するエンコードのストリームに対して未定義の動作が発生しますそれは確実に初期シフト状態で終了するわけではありません。**
エラーメッセージを送信できるように定義をintに変更してから、とを使用fseek()
しftell()
てファイルサイズを決定します。
int fsize(char* file) {
int size;
FILE* fh;
fh = fopen(file, "rb"); //binary mode
if(fh != NULL){
if( fseek(fh, 0, SEEK_END) ){
fclose(fh);
return -1;
}
size = ftell(fh);
fclose(fh);
return size;
}
return -1; //error
}
std cライブラリの使用に問題がない場合:
#include <sys/stat.h>
off_t fsize(char *file) {
struct stat filestat;
if (stat(file, &filestat) == 0) {
return filestat.st_size;
}
return 0;
}
また、Windowsアプリを構築している場合は、GetFileSizeExAPIを使用してください。CRTファイルのI/Oは、さまざまなシステムでのファイル表現の特殊性のために、特にファイルの長さを決定するために面倒です;)
fseekとftellを使用する方法と、この質問のスレッドを見つけました。この質問には、Cだけでは別の方法では実行できないという回答があります。
NSPR(Firefoxを強化するライブラリ)のような移植性ライブラリを使用できます。
この一連のコードを使用して、ファイルの長さを確認しました。
//opens a file with a file descriptor
FILE * i_file;
i_file = fopen(source, "r");
//gets a long from the file descriptor for fstat
long f_d = fileno(i_file);
struct stat buffer;
fstat(f_d, &buffer);
//stores file size
long file_length = buffer.st_size;
fclose(i_file);
ファイルサイズを返すシンプルでクリーンな関数を次に示します。
long get_file_size(char *path)
{
FILE *fp;
long size = -1;
/* Open file for reading */
fp = fopen(path, "r");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fclose(fp);
return
}
あなたはファイルを開くことができます、ファイルの底から相対的な0オフセットに行きます
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
fseekから返される値は、ファイルのサイズです。
私は長い間Cでコーディングしていませんでしたが、うまくいくはずだと思います。