2012-01-26 29 views
9

誰かが "重複"する前に、私は非常に徹底的にチェックしてきましたが、質問は非常にシンプルに見えますが、クリーンな回答はまだありません。Cで大きなファイルサイズを取得

私はポータブルCコードを探しています。このファイルは、そのファイルが4GBを超えていても、ファイルのサイズを提供することができます。

通常の方法(fseek、ftell)は、ファイルが< 2GBのままであれば正常に動作します。どこでもサポートされているので、私は同等のものを見つけようとしています。

残念ながら、更新されたメソッド(fseeko、ftello)はすべてのコンパイラでサポートされていません。たとえば、MinGWはそれを逃しています(明らかにMSVC)。さらに、いくつかのコメントは、新しい返品タイプ(off_t)が必ず2GBを超えるサイズをサポートしているとは考えていません。チェックする外部パラメータに依存する可能性があります。

明白なメソッド(fseeko64、ftello64)は、MSVCではサポートされていません。 MSは、対応する_fseeki64 & _ftelli64を提供します。これはすでに悪いですが、悪化します。実行時にこれらの機能を悪くサポートしているLinuxの設定があります。たとえば、GCC 4.4を使用しているPowerPCの私のDebian Squeezeは、fseeko64を使って "filesize"メソッドを生成します。fseeko64は常に0を返します(Ubuntu64では正常です)。 MinGWは2GB以上のランダムなごみに答えているようだ。

まあ、私は移植性が懸念されている限り、ちょっと無礼です。 #if #elseを作成する必要がある場合は、最初にOS &コンパイラ固有のメソッド(たとえば、MSVCのGetFileSize()など)に直接移動しないでください。

+3

「ポータブル」とは何ですか?ファイルを開くことさえできない多くのシステムがあります。さらに4GBを超えるサイズのファイルを開くことはできません。 –

答えて

8

あなたは言った:移植可能な方法はありません。私があなたの場合は、Windowsの場合はGetFileSize、POSIXの場合はstatを使用します。

+2

Windows上で '_stat64'を使用すると、コード* sorta *を同じに保つことができます。 – user7116

+1

@sixlettervariables:正しいですが、Windows上のすべてのコンパイラで実装されているかどうかはわかりませんが( 'GetFileSize'はWindows APIの一部ですが、常に利用できるはずです)。興味深い。 –

+0

私はそれを試みます。 – Cyan

6
int ch; 
FILE *f = fopen("file_to_analyse", "rb"); 
/* error checking ommited for brevity */ 
unsigned long long filesize = 0; /* or unsigned long for C89 compatability*/ 
while ((ch = fgetc(f)) != EOF) filesize++; 
fclose(f); 
/* error checking ommited for brevity */ 
+2

これは唯一の標準に準拠した方法ですが、私はあなたが気まぐれであることを願っています:サイズを知るために、ファイル全体、おそらく2GB以上の大きさ、1文字を読んでください(現在のファイルシステムは単純にファイルの属性です)普通のばかだ... –

+0

私はこれが冗談であることを望む。 – kichik

+2

ああ、いや、いや、いや...冗談だと教えてください。一方、問題は、効率的なものではなく、移植可能な方法に関するものです。これは確かにポータブルな方法です。 –

1
#include sys/stat.h 

off_t fsize(const char *filename) { 
    struct stat st; 

    if (stat(filename, &st) == 0) 
     return st.st_size; 

    return -1; 
} 
+0

多分あなたはその質問を読むことができます。 –

6

あなたは2 GB単位でファイルのファイルサイズの情報を取得するためにstat64 on Linux_stat64 on Windowsを使用することができるはず、との両方の機能が、使用中に非常によく似ています。あなたは、あまりにもWindows上でstat64を使用する#define秒のカップルを使用することができます。

#if __WIN32__ 
#define stat64 _stat64 
#endif 

しかし、これは動作するはずですが、Windows上での機能の_stat家族は本当に他の関数の周りだけのラッパーであることに留意すべきです追加リソースと時間オーバーヘッドを追加します。

+0

はい、興味深いですね。 – Cyan

2

lseek()(または_lseek())をSEEK_ENDとするとどうなりますか?求められたオフセットを返します。

_FILE_OFFSET_BITSの場合、lseek()の場合は64に設定して、64ビット値を返す必要があります(これはデフォルトである必要があります)。

+0

まだ試したことはありません。 lseek()はfseeko()と同じ種類の問題を抱えているようです:使用される型(off_t)は、いくつかの外部構成に応じて2GBを超える値をサポートする場合とサポートしない場合があります。 – Cyan

+0

@Attract:私は32/64bit Linuxで 'gcc'を使ってテストし、' VC10'を使って32bit win-vistaでテストしました。 – alk

2

私が実装され、次のことをテストしています

#if __WIN32__ 
#define stat64 _stat64 
#endif 

にMinGW64のGCCコンパイラ4.8.1およびLinux用のgcc 4.6.3 コンパイルした作品を使用しました。

OSXでは、statの再定義は必要ありません。

lstatとfstat関数私は、同様のマクロ#defineが動作することを期待しています。

+0

これは32ビット版(Linux、Windowsなど)で動作しますか? – Cyan

関連する問題