Вопросы | c

Как вы определяете размер файла в C?

Вопрос

andrewrk | 110679 просмотров | рейтинг: 1

Как я могу определить размер файла в байтах?

 #include <stdio.h>

unsigned int fsize(char* file){
  //what goes here?
}
 



Ответы

Orion Edwards

+ 0 -
Вам понадобится использовать библиотечную функцию для получения подробной информации о файле. Поскольку C полностью независим от платформы, вам нужно сообщить нам, для какой платформы / операционной системы вы разрабатываете!  


PabloG

+ 5 -
Если вы хорошо используете библиотеку 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;
}
 

 


andrewrk

+ -3 -
Вы можете открыть файл, перейти к 0 смещению относительно нижней части файла с помощью
 #define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)
 

значение, возвращаемое из fseek - это размер файла. Я давно не писал код на С, но думаю, что это должно сработать.  


NilObject

+ 28 -
Решение Мэтта должно работать, за исключением того, что это 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;
}
 

Исправил вашу скобку для вас тоже. ;) Обновление: это не самое лучшее решение. Он ограничен 4 ГБ файлами в Windows и, вероятно, медленнее, чем просто использование вызова конкретной платформы, такого как GetFileSizeEx или stat64.  


Chris Roberts

+ 12 -
** Не делай этого (почему?):
  Цитируя стандартный документ 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
}
 

 


Derek Park

+ 3 -
Быстрый поиск в Google нашел метод, использующий fseek и ftell, и ветку с этим вопросом с ответами, что это нельзя сделать просто на C другим способом. Вы можете использовать библиотеку переносимости, такую как NSPR (библиотека, поддерживающая Firefox), или проверить ее реализацию (скорее волосатую).  


Ted Percival

+ 69 -
Не используйте int. В наши дни файлы размером более 2 гигабайт часто встречаются как грязь Не используйте unsigned int. Файлы размером более 4 гигабайт часто встречаются как немного менее распространенная грязь Стандартная библиотека IIRC определяет off_t как 64-разрядное целое число без знака, которое каждый должен использовать. Мы можем переопределить его как 128-битный через несколько лет, когда у нас появятся 16 эксабайтных файлов. Если вы работаете в Windows, вы должны использовать GetFileSizeEx - он на самом деле использует 64-разрядное целое число со знаком, поэтому они начнут сталкиваться с проблемами с 8 эксабайтными файлами. Глупый Microsoft! :-)  


Nickolay

+ 4 -
А если вы создаете приложение для Windows, используйте API GetFileSizeEx, так как ввод / вывод файла CRT является грязным, особенно для определения длины файла, из-за особенностей представления файлов в разных системах;)


Orion Edwards

+ 0 -
На основе кода 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».  


PabloG

+ 5 -
Я использовал этот набор кода, чтобы найти длину файла.
 //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);
 

 


andrewrk

+ -3 -
Глядя на вопрос, ftell может легко получить количество байтов.
   long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);
 

 


NilObject

+ 28 -
Попробуйте это -
 fseek(fp, 0, SEEK_END);
unsigned long int file_size = ftell(fp);
rewind(fp);
 

Сначала это делается, ищите до конца файла; затем сообщите, где находится указатель файла. И наконец (это необязательно), он перематывает назад к началу файла. Обратите внимание, что fp должен быть двоичным потоком. file_size содержит количество байтов, которое содержит файл. Обратите внимание, что поскольку (в соответствии с climits.h) тип unsigned long ограничен 4294967295 байтами (4 гигабайта), вам нужно будет найти другой тип переменной, если вы, вероятно, имеете дело с файлами большего размера.


Теги

c | file | io | filesize

Похожие вопросы:

Как я могу получить размер файла в C?