Вопрос

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

#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; 
}

Изменения:

  • Сделал аргумент filename равным 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 экзабайт.Глупый 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.

** Не делай этого (почему?):

Цитирую стандартный документ 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;
}

POSIX

Тот Самый POSIX у standard есть свой собственный метод получения размера файла.
Включать в себя 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 напрямую не предоставляет способ определения длины файла.
Нам придется напрячь свой разум.На данный момент мы будем использовать подход seek!

Краткий обзор

  • Ищите файл до конца, используя fseek(3).
  • Получите текущую позицию, используя ftell(3).

Пример

#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-файловый ввод-вывод является беспорядочным, особенно для определения длины файла, из-за особенностей представления файлов в разных системах ;)

Быстрый поиск в 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 гигабайта), вам нужно будет найти другой тип переменной, если вы, вероятно, будете иметь дело с файлами большего размера.

Вот простая и понятная функция, которая возвращает размер файла.

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 
}

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

Рассматривая этот вопрос, ftell можно легко получить количество байт.

  long size ;
  size = ftell(FILENAME);
  printf("total size is %ld bytes",size);

Вы можете открыть файл, перейдя к смещению 0 относительно нижней части файла с помощью

#define SEEKBOTTOM   2

fseek(handle, 0, SEEKBOTTOM)  

значение, возвращаемое из fseek, является размером файла.

Я долгое время не программировал на C, но я думаю, что это должно сработать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top