2012-01-26 2 views
9

누구든지 "복제본"이라는 불평을하기 전에 나는 매우 철저히 검사를 해왔지만 질문은 아주 간단 해 보이지만 깨끗한 대답은 아직없는 것 같습니다.C로 큰 파일 크기 가져 오기

나는이 파일이 4GB보다 크더라도 휴대용 C 코드을 찾고 있는데, 이는 파일 크기를 제공 할 수 있습니다.

파일이 < 2GB 인 한 일반적인 방법 (fseek, ftell)은 정상적으로 작동합니다. 어디서나 지원이 잘되어있어서 동등한 것을 찾으려고합니다.

업데이트 된 메서드 (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를 여러 개 만들 필요가 있다면 먼저 OSV & 컴파일러의 구체적인 방법 (예 : MSVC의 GetFileSize())으로 이동하십시오.

+3

"휴대용"에 대한 정의는 무엇입니까? 파일을 열 수없는 많은 시스템이 있습니다. 크기가 4GB가 넘는 파일은 열 수 없습니다. –

답변

8

당신이 말했듯이 : 이식성있는 방법은 없습니다. 내가 너라면, 윈도우에서는 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 이상의 큰 파일을 읽는 것입니다 (현재 파일 시스템은 단순히 파일의 속성입니다)) 보통 바보 야. –

+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_BITSlseek()에 대해 64으로 정의되어야 64 비트 값을 반환 할 수 있습니다 (기본 값이어야 함).

+0

아직 시도하지 않았습니다. lseek()는 fseeko()와 같은 종류의 문제가있는 것 같습니다 : 사용 된 유형 (off_t)은 일부 외부 구성에 따라 2GB를 초과하는 값을 지원할 수도 있고 지원하지 않을 수도 있습니다. – Cyan

+0

@Attract : 저는 32/64bit 리눅스에서'gcc'를 사용하고 32bit win-vista에서는'VC10'을 사용하여 이것을 테스트했습니다. – 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