ファイルのサイズをバイト単位で知るにはどうすればよいですか?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file
、なんでFILE* file
?-1
ファイルのサイズをバイト単位で知るにはどうすればよいですか?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
char* file
、なんでFILE* file
?-1
回答:
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
と、最大2 GBの値しか保持できません。詳細については、Linuxでの大容量ファイルサポートの「LFSの使用」セクションを参照してください。
fseek
+ ftell
を使用します。
fseek
+ ftell
を使用します。 いいえ。C標準では、バイナリファイルfseek()
に対するto SEEK_END
は未定義の動作であると明確に規定されています。 7.19.9.2 fseek
関数 ...バイナリストリームfseek
はSEEK_END
、以下のように、pの脚注234からのwhence値の呼び出しを意味的にサポートする必要はありません。リンクされたC標準の267。これは、未定義の動作としてバイナリストリームで明確にラベル付けfseek
さSEEK_END
れます。。
使わない 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
。
long int
から戻りftell()
ます。 (unsigned long)
キャストは、関数によって既に制限されている範囲を改善しません。 ftell()
エラーの場合は-1を返し、キャストで難読化されます。fsize()
と同じタイプを返すことを提案しftell()
ます。
**これを行わないでください(なぜですか?):
オンラインで見つけたC99標準ドキュメントの引用:「ファイル位置インジケーターをファイルの終わりに設定する
fseek(file, 0, SEEK_END)
と、バイナリストリーム(後続のnull文字が続く可能性があるため)または状態依存のエンコーディングのストリームに対して未定義の動作が発生します。初期シフト状態で確実に終了するわけではありません。**
エラーメッセージを送信できるように定義を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
}
fseeko
およびftello
(またはfseek
とftell
、あなたがして働くことができるサイズのファイルの制限と前者と幸せずに立ち往生している場合)、ファイルの長さを決定するための正しい方法です。stat
ベースのソリューションは、多くの「ファイル」(ブロックデバイスなど)では機能せず、非POSIX系のシステムに移植できません。
POSIX標準ではファイルサイズを取得するための独自のメソッドを持っています。
関数を使用する
ためにsys/stat.h
ヘッダーを含めます。
stat(3)
。st_size
プロパティを取得します。注:サイズはに制限され4GB
ます。Fat32
ファイルシステムでない場合は、64ビットバージョンを使用してください。
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat info;
stat(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat64 info;
stat64(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
ANSI Cは、直接ファイルの長さを決定する方法を提供しません。
私たちは心を使わなければならないでしょう。ここでは、シークアプローチを使用します。
#include <stdio.h>
int main(int argc, char** argv)
{
FILE* fp = fopen(argv[1]);
int f_size;
fseek(fp, 0, SEEK_END);
f_size = ftell(fp);
rewind(fp); // to back to start again
printf("%s: size=%ld", (unsigned long)f_size);
}
ファイルが
stdin
パイプの場合。POSIX、ANSI Cは機能しません。 ファイルがパイプまたはの場合は
戻り0
ますstdin
。意見:代わりにPOSIX標準を使用する必要があります。なぜなら、それは64ビットをサポートしているからです。
struct _stat64
そして__stat64()
_windowsため。
また、Windowsアプリを構築している場合は、GetFileSizeEx APIを使用してください。CRTファイルのI / Oは、さまざまなシステムでのファイル表現の特殊性のために、特にファイル長を決定するのに面倒なので、;)
このコードセットを使用して、ファイルの長さを調べました。
//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);
これを試して -
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
これが最初に行うことは、ファイルの最後までシークすることです。次に、ファイルポインターの場所を報告します。最後に(これはオプションです)、ファイルの先頭に巻き戻します。ご了承くださいfp
バイナリストリームで必要があります。
file_sizeには、ファイルに含まれるバイト数が含まれます。(climits.hによると)unsigned long型は4294967295バイト(4ギガバイト)に制限されているため、それより大きいファイルを処理する可能性がある場合は、別の変数型を見つける必要があります。
ftell
は、ファイルから読み取ることができるバイト数を表す値を返しません。
あなたはファイルを開くことができ、ファイルの下部からの相対オフセット0に移動します
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
fseekから返される値はファイルのサイズです。
私は長い間Cでコーディングしていませんでしたが、うまくいくと思います。
質問を見て、ftell
簡単にバイト数を取得できます。
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftell
引数として、ファイル名ではなくファイル記述子が必要です。
ftell
はファイル記述子を想定していませんFILE*
。代わりにを想定しています。まずmanページを見てください!
fseek()
は、ファイルの終わりをシークするために最初に使用する必要があり、また、文字列ではなくをftell()
期待しているFILE *
からです。あなたはあなたの答えを肉付けするのによく役立つでしょう。