Получить большой размер файла в C - PullRequest
9 голосов
/ 27 января 2012

Прежде чем кто-либо жаловался на "дубликат", я довольно тщательно проверял SO, но, похоже, пока нет четкого ответа, хотя вопрос выглядит довольно простым.

Я ищу переносимый код C , который может предоставить размер файла, даже если такой файл больше 4 ГБ.

Обычный метод (fseek, ftell) работает нормально, пока файл остается <2 ГБ. Это довольно хорошо поддерживается везде, поэтому я пытаюсь найти что-то эквивалентное. </p>

К сожалению, обновленные методы (fseeko, ftello) поддерживаются не всеми компиляторами. Например, MinGW пропустит это (и, очевидно, MSVC). Кроме того, некоторые комментарии заставляют меня поверить, что новый тип возвращаемого значения (off_t) не обязательно поддерживает размер> 2 ГБ, это может зависеть от некоторых внешних параметров, которые необходимо проверить.

Однозначные методы (fseeko64, ftello64) не поддерживаются MSVC. MS предоставляет их эквивалент, _fseeki64 & _ftelli64. Это уже плохо, но становится хуже: некоторые конфигурации Linux, кажется, плохо поддерживают эти функции во время выполнения. Например, мой Debian Squeeze на PowerPC, использующий GCC 4.4, создаст метод «размер файла» с использованием fseeko64, который всегда возвращает 0 (хотя он отлично работает для Ubuntu64). MinGW, кажется, отвечает на случайный мусор выше 2 ГБ.

Ну, я немного не в курсе, что касается переносимости. И если мне нужно сделать кучу #if #else, то почему бы не перейти прямо к специфике методов OS и компиляторов, например, GetFileSize () для MSVC.

Ответы [ 6 ]

8 голосов
/ 27 января 2012

Вы сказали это: нет портативного метода; на вашем месте я бы просто использовал GetFileSize в Windows и stat в POSIX.

7 голосов
/ 27 января 2012

Вы можете использовать stat64 в Linux и _stat64 в Windows , чтобы получить информацию о размере файла для файлов размером более 2 ГБ, и обе функции очень похожи в использование. Вы также можете использовать пару #define s для использования stat64 в Windows:

#if __WIN32__
#define stat64 _stat64
#endif

Однако, хотя это должно сработать, следует отметить, что семейство функций _stat в Windows на самом деле является просто оболочкой для других функций и добавит дополнительные ресурсы и накладные расходы времени.

5 голосов
/ 27 января 2012
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 */
3 голосов
/ 02 сентября 2013

Я реализовал и протестировал следующее:

#if __WIN32__
#define stat64 _stat64
#endif

, используя MinGW64 gcc compiler 4.8.1 и Linux gcc 4.6.3, компилирует и работает.

В OSX переопределение статистики не требуется.

для функций lstat и fstat. Я ожидаю, что аналогичный макрос #defines будет работать.

2 голосов
/ 27 января 2012

Как насчет использования lseek() (или _lseek()) с SEEK_END?Возвращает искомое смещение.

В linux _FILE_OFFSET_BITS необходимо определить как 64 для lseek(), чтобы получить 64-битные значения (которые в любом случае должны быть по умолчанию).

1 голос
/ 27 января 2012
#include sys/stat.h

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

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

    return -1; 
}
...