Как я могу определить размер файла в байтах?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
Как я могу определить размер файла в байтах?
#include <stdio.h>
unsigned int fsize(char* file){
//what goes here?
}
Ответы:
На основе кода 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;
}
Изменения:
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» .
fseek+, ftellпредложенный Дереком.
fseek+, ftellпредложенный Дереком. Нет. Стандарт C специально указывает, что fseek()для SEEK_ENDдвоичного файла поведение undefined. 7.19.9.2 fseekФункция ... Двоичный поток не обязательно должен поддерживать fseekвызовы со значением источникаSEEK_END , равным , как указано ниже, из сноски 234 на стр. 267 связанных C стандарта, и которые специфически этикетками , fseekчтобы SEEK_ENDв двоичном потоке в качестве неопределенного поведения. .
Не используйте int. Файлы размером более 2 гигабайт в наши дни стали обычным явлением
Не используйте unsigned int. Файлы размером более 4 гигабайт обычно встречаются как немного менее распространенная грязь.
IIRC стандартная библиотека определяет off_tкак 64-битное целое число без знака, которое следует использовать всем. Мы можем переопределить это значение до 128 бит через несколько лет, когда мы начнем иметь файлы размером 16 эксабайт.
Если вы работаете в Windows, вам следует использовать GetFileSizeEx - он фактически использует 64-битное целое число со знаком, поэтому они начнут сталкиваться с проблемами с 8-ми эксабайтными файлами. Глупый Microsoft! :-)
Решение Мэтта должно работать, за исключением того, что это 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.
long intиз ftell(). (unsigned long)приведение не улучшает диапазон, который уже ограничен функцией. ftell()вернуть -1 при ошибке, и это будет запутано с приведением. Предлагаю fsize()вернуть тот же тип, что и ftell().
** Не делайте этого ( почему? ):
Цитата из стандартного документа 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
}
fseekoи ftello(или fseekи ftellесли вы застряли без первого и счастливым с ограничениями на размеры файлов вы можете работать с) , являются правильным способом , чтобы определить длину файла. statРешения на основе не работают со многими «файлами» (такими как блочные устройства) и не переносятся на системы, отличные от 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 непосредственно не обеспечивает способ определить длину файла.
Придется использовать свой разум. А пока воспользуемся методом поиска!
#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-битную версию.
struct _stat64и __stat64()для _Windows.
Если вас устраивает библиотека 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);
Попробуй это --
fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
Сначала выполняется поиск до конца файла; затем сообщите, где находится указатель файла. Наконец (это необязательно) он перематывает назад к началу файла. Обратите внимание, что это fpдолжен быть двоичный поток.
file_size содержит количество байтов, содержащихся в файле. Обратите внимание, что, поскольку (согласно climits.h) тип unsigned long ограничен 4294967295 байтами (4 гигабайта), вам нужно будет найти другой тип переменной, если вы, вероятно, будете иметь дело с файлами большего размера.
ftellне возвращается значение, представляющее количество байтов, которые могут быть прочитаны из файла.
У меня есть функция, которая хорошо работает только с stdio.h. Мне он очень нравится, работает очень хорошо и довольно лаконично:
size_t fsize(FILE *File) {
size_t FSZ;
fseek(File, 0, 2);
FSZ = ftell(File);
rewind(File);
return FSZ;
}
Вот простая и понятная функция, которая возвращает размер файла.
long get_file_size(char *path)
{
FILE *fp;
long size = -1;
/* Open file for reading */
fp = fopen(path, "r");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fp.close();
return
}
Вы можете открыть файл, перейти к 0 смещению относительно нижнего края файла с помощью
#define SEEKBOTTOM 2
fseek(handle, 0, SEEKBOTTOM)
значение, возвращаемое из fseek, - это размер файла.
Я давно не кодировал на C, но думаю, что это должно сработать.
Глядя на вопрос, ftellлегко можно получить количество байтов.
long size = ftell(FILENAME);
printf("total size is %ld bytes",size);
ftellожидает в качестве аргумента дескриптор файла, а не имя файла.
ftellне ожидает файловый дескриптор, FILE*вместо этого ожидает . Сначала см. Справочную страницу!