Как вы определяете размер файла в C?
Как я могу определить размер файла, в байтах?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
13 ответов:
на основе кода 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
будет содержать только значения до 2 ГБ. См. раздел" Использование LFS " в поддержка больших файлов в Linux для сведения.
не используйте
int
. Файлы размером более 2 гигабайт в наши дни распространены как грязьне используйте
unsigned int
. Файлы размером более 4 гигабайт распространены как некоторые чуть менее распространенные грязиIIRC стандартная библиотека определяет
off_t
как беззнаковое 64-битное целое число, которое все должны использовать. Мы можем переопределить это, чтобы быть 128 бит, через несколько лет, когда мы начали заниматься 16 эксабайт, файлы шляется.Если вы находитесь на Windows, вы должны использовать GetFileSizeEx - он фактически использует 64-битное целое число со знаком, поэтому они начнут сталкиваться с проблемами с файлами 8 exabyte. Глупый Microsoft! : -)
решение Мэтта должно работать, за исключением того, что это C++ вместо C, и начальный tell не должен быть необходим.
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; }
исправлена ваша скобка для вас тоже. ;)
обновление: это не самое лучшее решение. Это ограничено 4 ГБ файлов на Windows, и это, вероятно, медленнее, чем просто с помощью платформы конкретного вызова, как
GetFileSizeEx
илиstat64
.
**Не делайте этого (почему?):
цитируя стандартный документ 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 }
Если вы в порядке с использованием библиотеки 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; }
и если вы создаете приложение для Windows, используйте GetFileSizeEx API как CRT файл ввода-вывода является грязным, особенно для определения длины файла, из-за особенностей в представлении файлов на разных системах ;)
быстрый поиск в Google нашел метод с использованием fseek и ftell и поток с этим вопросом с ответами, что это не может быть сделано только в C по-другому.
вы можете использовать библиотеку переносимости, как NSPR (библиотека, которая питает Firefox) или проверьте его реализации (довольно волосатые).
я использовал этот код, чтобы найти длину файла.
//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);
вот простая и чистая функция, которая возвращает размер файла.
long get_file_size(char *path) { FILE *fp; /* Open file for reading */ fp = fopen(path, "r"); fseek(fp, 0, SEEK_END); return ftell(fp); }
попробовать это...
fseek(fp, 0, SEEK_END); unsigned long int file_size = ftell(fp); rewind(fp);
что это делает, во-первых, искать до конца файла; затем, сообщить, где находится указатель файла. Наконец (это необязательно) он перематывается обратно в начало файла. Обратите внимание, что
fp
должен быть двоичный поток.file_size содержит количество байтов, содержащихся в файле. Обратите внимание, что с тех пор (согласно climits.h) беззнаковый длинный тип ограничен 4294967295 байтами (4 гигабайта) вам нужно будет найти другой тип переменной, если вы, вероятно, будете иметь дело с файлами большего размера.
вам нужно будет использовать функцию библиотеки для получения сведений о файле. Поскольку C полностью независим от платформы, вам нужно будет сообщить нам, для какой платформы / операционной системы вы разрабатываете!