Я ищу эквивалент 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?
Думаю fsize = _filelength(fileno(hfile));
-> fsize = _filelength(hfile);
Возможный дубликат Как определить размер файла на C?, Как я могу получить размер файла на C?, Правильный способ получить размер файла на C, Как получить длину файла в c? и т. д.
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, это не то же самое!
Я определенно согласен с изучением API Linux. Я не уверен, что согласен с их использованием. Если вы пишете код, который работает в Windows и Linux, вам вполне может понадобиться уровень переносимости, и вы можете решить, что ваш уровень переносимости больше похож на winapi, чем на Linux.
errno
никогда не равен -1. Что-то не так. Покажите немного минимальный воспроизводимый пример в вашем вопросе.
Вы должны искать в файле.
fseek(file, 0L, SEEK_END);
Затем получите текущую позицию:
fileSize = ftell(file);
Затем, чтобы вернуть позицию в исходное состояние, используйте:
rewind(file);
Это не совсем соответствует требованиям C. Это undefined поведение для поиска до конца двоичного потока, а вы не может использовать ftell()
для получения размера текстового потока в байтах
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;
}
С чего вы взяли, что это неверно? Не компилируется!