Ответов (13)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;
}
Изменения:
- Сделал аргумент имени файла 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» .
Я использовал этот набор кода, чтобы найти длину файла.
//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);
Попробуй это --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
Сначала выполняется поиск до конца файла; затем сообщите, где находится указатель файла. Наконец (это необязательно) он перематывает назад к началу файла. Обратите внимание, что это fp
должен быть двоичный поток.
file_size содержит количество байтов, содержащихся в файле. Обратите внимание: поскольку (согласно climits.h) тип unsigned long ограничен 4294967295 байтами (4 гигабайта), вам нужно будет найти другой тип переменной, если вы, вероятно, будете иметь дело с файлами большего размера.
POSIX
Стандарт POSIX имеет свой собственный метод получения размера файла.
Включите sys/stat.h
заголовок, чтобы использовать функцию.
Синопсис
- Получите статистику файлов, используя
stat(3)
. - Получите
st_size
собственность.
Примеры
Примечание : он ограничивает размер до 4GB
. Если не Fat32
файловая система, используйте 64-битную версию!
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat info;
stat(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
struct stat64 info;
stat64(argv[1], &info);
// 'st' is an acronym of 'stat'
printf("%s: size=%ld\n", argv[1], info.st_size);
}
ANSI C (стандарт)
ANSI C непосредственно не обеспечивает способ определить длину файла.
Придется использовать свой разум. А пока воспользуемся методом поиска!
Синопсис
Пример
#include <stdio.h>
int main(int argc, char** argv)
{
FILE* fp = fopen(argv[1]);
int f_size;
fseek(fp, 0, SEEK_END);
f_size = ftell(fp);
rewind(fp); // to back to start again
printf("%s: size=%ld", (unsigned long)f_size);
}
Если напильник
stdin
или труба. POSIX, ANSI C работать не будут.
Он вернется,0
если файл является каналом илиstdin
.Мнение : Вместо этого вам следует использовать стандарт POSIX . Потому что он поддерживает 64-битную версию.
А если вы создаете приложение для Windows, используйте GetFileSizeEx API, поскольку ввод-вывод файла CRT беспорядочный, особенно для определения длины файла, из-за особенностей представления файлов в разных системах;)
Я нашел метод, использующий fseek и ftell, и ветку с этим вопросом с ответами, что это невозможно сделать на одном только C другим способом.
Вы можете использовать библиотеку переносимости, такую как NSPR (библиотека, на которой работает Firefox).
Решение Мэтта должно работать, за исключением того, что это 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 он ограничен файлами размером 4 ГБ и, вероятно, медленнее, чем простой вызов, зависящий от платформы, например GetFileSizeEx
или stat64
.
Не используйте int
. Файлы размером более 2 гигабайт в наши дни стали обычным явлением
Не используйте unsigned int
. Файлы размером более 4 гигабайт обычно встречаются в качестве немного менее распространенной грязи.
IIRC стандартная библиотека определяет off_t
как 64-битное целое число без знака, которое должен использовать каждый. Мы можем переопределить это значение до 128 бит через несколько лет, когда у нас начнут появляться файлы размером 16 эксабайт.
Если вы работаете в Windows, вам следует использовать GetFileSizeEx - он фактически использует подписанное 64-битное целое число, поэтому они начнут сталкиваться с проблемами с 8-ми эксабайтными файлами. Глупый Microsoft! :-)
** Не делайте этого ( почему? ):
Цитата из стандартного документа 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
}