Как получить длину файла в C в Linux?

Я ищу эквивалент Microsoft _filelength в Linux. Я пробовал это, но это неверно.

long _filelength(char *f)
{
    struct stat st;
    stat(f, &st);
    return st.st_size;
}

if ((hfile = fopen("data.arp","rb"))!=NULL)
    fsize = _filelength(fileno(hfile));

Как мне узнать длину файла на C в Linux?

С чего вы взяли, что это неверно? Не компилируется!

Basile Starynkevitch 01.05.2018 17:25

Думаю fsize = _filelength(fileno(hfile)); -> fsize = _filelength(hfile);

Achal 01.05.2018 17:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
4 557
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

I'm looking for the equivalent of _filelength in linux.

Это очень неправильный подход и показывает неправильное мышление. Не существует точного эквивалента Windows _filelength в Linux.. Linux - это нет Windows, а Windows - это не Linux. Каждая операционная система имеет свой собственный API и свое собственное видение файлов (в Linux это inode, см. Ответ индекс (7), а также это ...), процессов и т. д. Linux в основном совместим с POSIX, поэтому изучите POSIX и прочтите книга по системному программированию Linux, возможно, старый ALP или что-то новее. Не ожидайте (и даже не пытайтесь) найти эквивалент каждой функции Windows или WinAPI в Linux. См. вступление (2), системные вызовы (2), вступление (3).

Читайте внимательнее стат (2). Он принимает строку (некоторый путь к файлу), а не дескриптор файла (как это делает fstat), как указано в fileno (3). Он может выйти из строя (и вам нужно понять, почему, вероятно, с помощью ошибка (3), который никогда не бывает отрицательным).

Кстати, идентификаторы с именем, начинающимся с _, зарезервированы.

Возможно, вы могли бы попробовать:

long filelength(const char*filpath) { // don't use that. Learn POSIX API
   struct stat st;
   if (stat(filpath, &st)) /*failure*/
      return -1; // when file does not exist or is not accessible
   return (long) st.st_size;
}

но на практике вам лучше использовать stat непосредственно в вашей программе (и проверьте ошибка (3) при сбое, а не просто возвращать -1, как я сделал выше), и вам, вероятно, следует использовать в нем метаданные Другие, возвращаемые stat.

Linux (и Unix) также имеют разреженные файлы, жесткие ссылки, файлы устройства, символические ссылки, анонимные файлы (например, все еще открытые inodes, но больше не присутствующие в файловой системе), фифо (7)-s, unix (7) сокеты и т. д. их (но у них нет точного эквивалента в Windows).

Читайте также Операционные системы: три простых штуки

Вы можете использовать многоплатформенные фреймворки, такие как Поко, Увеличение или Qt. Они пытаются предоставить некоторые общие абстракция над несколькими операционными системами (но некоторые детали все еще имеют значение, и их трудно скрыть или абстрагироваться; например, файл дорожка не то же самое в Windows и в Linux. См. path_resolution (7) ...)

Вы должны компилировать со всеми предупреждениями и отладочной информацией (так что gcc -Wall -Wextra -g с GCC). Тогда использовать отладчик gdb. Вы также можете использовать strace (1), чтобы понять системные вызовы, выполняемый вашей программой.

Да. errno проверяли? Я пытаюсь объяснить, что у вас неправильный подход. Измените свое мышление и сделайте его дружественным к Linux. Не думайте терминами WinAPI. Изучите POSIX API, это не то же самое!

Basile Starynkevitch 01.05.2018 17:47

Я определенно согласен с изучением API Linux. Я не уверен, что согласен с их использованием. Если вы пишете код, который работает в Windows и Linux, вам вполне может понадобиться уровень переносимости, и вы можете решить, что ваш уровень переносимости больше похож на winapi, чем на Linux.

Sam Hartman 01.05.2018 17:57
errno никогда не равен -1. Что-то не так. Покажите немного минимальный воспроизводимый пример в вашем вопросе.
Basile Starynkevitch 01.05.2018 18:04

Вы должны искать в файле.

fseek(file, 0L, SEEK_END);

Затем получите текущую позицию:

fileSize = ftell(file);

Затем, чтобы вернуть позицию в исходное состояние, используйте:

rewind(file);

Это не совсем соответствует требованиям C. Это undefined поведение для поиска до конца двоичного потока, а вы не может использовать ftell() для получения размера текстового потока в байтах

Andrew Henle 02.05.2018 11:26
Ответ принят как подходящий
FILE *fp = fopen("filename", "rb");
fseek(fp, 0, SEEK_END);
int lengthOfFile = ftell(fp);
fclose(fp);

Может ты сможешь попробовать с этим.

size_t _filelength(int filedes)
{
    off_t pos = lseek(filedes, 0, SEEK_CUR);
    if (pos != (off_t)-1)
    {
        off_t size = lseek(filedes, 0, SEEK_END);
        lseek(filedes, pos, SEEK_SET);
        return (size_t)size;
    }
    return (off_t)-1;
}

Другие вопросы по теме