154

ファイルのサイズをバイト単位で把握するにはどうすればよいですか?

#include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
4

14 に答える 14

164

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; 
}

変更点:

  • filename引数をaにしました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の使用」セクションを参照してください。

于 2008-08-12T00:55:48.313 に答える
79

使用しないでくださいint。最近の汚れとして、サイズが2ギガバイトを超えるファイルが一般的です。

使用しないでくださいunsigned int。サイズが4ギガバイトを超えるファイルは、少し一般的ではない汚れとして一般的です。

IIRCは、標準ライブラリoff_tで符号なし64ビット整数として定義されています。これは誰もが使用する必要があるものです。16エクサバイトのファイルがぶらぶらし始めたら、数年で128ビットに再定義できます。

Windowsを使用している場合は、GetFileSizeExを使用する必要があります。実際には符号付き64ビット整数を使用するため、8エクサバイトのファイルで問題が発生し始めます。愚かなマイクロソフト!:-)

于 2008-08-11T22:09:03.907 に答える
32

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

于 2008-08-11T21:26:15.493 に答える
14

**これを行わないでください(なぜですか?):

オンラインで見つけた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
}
于 2008-08-11T21:28:05.737 に答える
4

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;
}
于 2008-08-11T21:21:42.850 に答える
4

また、Windowsアプリを構築している場合は、GetFileSizeExAPIを使用してください。CRTファイルのI/Oは、さまざまなシステムでのファイル表現の特殊性のために、特にファイルの長さを決定するために面倒です;)

于 2008-08-12T00:15:35.853 に答える
3

fseekとftellを使用する方法と、この質問のスレッドを見つけました。この質問には、Cだけでは別の方法では実行できないという回答があります。

NSPR(Firefoxを強化するライブラリ)のような移植性ライブラリを使用できます。

于 2008-08-11T21:30:08.353 に答える
2

この一連のコードを使用して、ファイルの長さを確認しました。

//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);
于 2014-02-08T01:54:26.347 に答える
-2

ファイルサイズを返すシンプルでクリーンな関数を次に示します。

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 
}
于 2016-06-06T15:27:52.440 に答える
-3

あなたはファイルを開くことができます、ファイルの底から相対的な0オフセットに行きます

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

fseekから返される値は、ファイルのサイズです。

私は長い間Cでコーディングしていませんでしたが、うまくいくはずだと思います。

于 2008-08-11T21:23:59.787 に答える