Как определить размер(длину) файла в Линукс средствами С++
От: Dimitar  
Дата: 28.11.07 10:25
Оценка:
Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?
Более подробно: имеется написанная функция
MyGetFileLength(int fd)
{
#ifdef WIN32
   return filelength(fd);
#elif defined UNIX_KERNEL
   return -1; // Вот сюда то и надо что-то поставить...
#endif
}



28.11.07 14:36: Перенесено модератором из 'C/C++' — Кодт
Re: Как определить размер(длину) файла в Линукс средствами С
От: Аноним  
Дата: 28.11.07 11:08
Оценка:
Здравствуйте, Dimitar, Вы писали:

D>Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?

D>Более подробно: имеется написанная функция
D>
D>MyGetFileLength(int fd)
D>{
D>#ifdef WIN32
D>   return filelength(fd);
D>#elif defined UNIX_KERNEL
D>   return -1; // Вот сюда то и надо что-то поставить...
D>#endif
D>}
D>

Так пойдет?
off_t size = lseek(fd, 0, SEEK_END);
Re: Как определить размер(длину) файла в Линукс средствами С
От: Alexey Borodin alexey-borodin@narod.ru
Дата: 28.11.07 11:09
Оценка:
Здравствуйте, Dimitar, Вы писали:

D>Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?

D>Более подробно: имеется написанная функция
D>
D>MyGetFileLength(int fd)
D>{
D>#ifdef WIN32
D>   return filelength(fd);
D>#elif defined UNIX_KERNEL
D>   return -1; // Вот сюда то и надо что-то поставить...
D>#endif
D>}
D>


boost -> filesystem -> file_size (введена недавно).
Re: Как определить размер(длину) файла в Линукс средствами С
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 28.11.07 11:09
Оценка: +1
Здравствуйте, Dimitar, Вы писали:

D>Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?

D>Более подробно: имеется написанная функция
D>
D>MyGetFileLength(int fd)
D>{
D>#ifdef WIN32
D>   return filelength(fd);
D>#elif defined UNIX_KERNEL
D>   return -1; // Вот сюда то и надо что-то поставить...
D>#endif
D>}
D>


fstat, затем смотреть значение поля st_size в структуре stat.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Как определить размер(длину) файла в Линукс средствам
От: Аноним  
Дата: 28.11.07 11:12
Оценка:
Здравствуйте, Alexey Borodin, Вы писали:

AB>Здравствуйте, Dimitar, Вы писали:


D>>Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?

D>>Более подробно: имеется написанная функция
D>>
D>>MyGetFileLength(int fd)
D>>{
D>>#ifdef WIN32
D>>   return filelength(fd);
D>>#elif defined UNIX_KERNEL
D>>   return -1; // Вот сюда то и надо что-то поставить...
D>>#endif
D>>}
D>>


AB>boost -> filesystem -> file_size (введена недавно).

у меня такое вроде работает под лин и под win
long GetFileSize( const char * filename ) { 
 FILE *fp = fopen( filename, "rb" );
 long res;
 fpos_t position; 

 if ( fgetpos(fp, &position) )       //запоминаем текущую позицию
        {fclose(fp); 
             return -1;}         //ошибка получения текущей позиции файла

 fseek(fp, 0, SEEK_END);         //смещаемся в конец файла
 res = ftell(fp);             //читаем положение указателя в конце файла

 if ( fsetpos(fp, &position) )       //кладем откуда взяли (позицию файла)
        {fclose(fp);
         return -1;}         //ошибка установки позиции файла

  fclose(fp);
  return res;
}
Re: Как определить размер(длину) файла в Линукс средствами С
От: MShura  
Дата: 28.11.07 11:36
Оценка:
D>
D>MyGetFileLength(int fd)
D>{
D>#ifdef WIN32
D>   return filelength(fd);
D>#elif defined UNIX_KERNEL
D>   return -1; // Вот сюда то и надо что-то поставить...
D>#endif
D>}
D>


Что означает UNIX_KERNEL?
Это ваш внутренний дефайн?

В ядре linux (unix) нет предлагаемых функций из C-runtime.
Re[2]: Как определить размер(длину) файла в Линукс средствам
От: Dimitar  
Дата: 28.11.07 12:05
Оценка:
Здравствуйте, MShura, Вы писали:

D>>
D>>MyGetFileLength(int fd)
D>>{
D>>#ifdef WIN32
D>>   return filelength(fd);
D>>#elif defined UNIX_KERNEL
D>>   return -1; // Вот сюда то и надо что-то поставить...
D>>#endif
D>>}
D>>


MS>Что означает UNIX_KERNEL?

MS>Это ваш внутренний дефайн?

MS>В ядре linux (unix) нет предлагаемых функций из C-runtime.


Да, дефайны UNIX_KERNEL и WIN32 наши внутренние. Я в курсе что в ядре linux нет предлагаемых функций из C-runtime, поэтому собственно и возник вопрос
Re[2]: Как определить размер(длину) файла в Линукс средствам
От: Dimitar  
Дата: 28.11.07 12:08
Оценка:
Здр
авствуйте, Аноним, Вы писали:

А>Здравствуйте, Dimitar, Вы писали:


D>>Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?

D>>Более подробно: имеется написанная функция
D>>
D>>MyGetFileLength(int fd)
D>>{
D>>#ifdef WIN32
D>>   return filelength(fd);
D>>#elif defined UNIX_KERNEL
D>>   return -1; // Вот сюда то и надо что-то поставить...
D>>#endif
D>>}
D>>

А>Так пойдет?
А>
А>off_t size = lseek(fd, 0, SEEK_END);
А>


Да, на мой взгляд, это вполне подходящее решение Спасибо!
Re[3]: Как определить размер(длину) файла в Линукс средствам
От: Аноним  
Дата: 28.11.07 12:29
Оценка:
А>>Так пойдет?
А>>
А>>off_t size = lseek(fd, 0, SEEK_END);
А>>


D>Да, на мой взгляд, это вполне подходящее решение Спасибо!

Только надо будет еще не забыть восстановить предыдущую позицию указателя. Или воспользоваться fstat, как предложил eao197.
Re[4]: Как определить размер(длину) файла в Линукс средствам
От: Dimitar  
Дата: 28.11.07 16:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Так пойдет?

А>>>
А>>>off_t size = lseek(fd, 0, SEEK_END);
А>>>


D>>Да, на мой взгляд, это вполне подходящее решение Спасибо!

А>Только надо будет еще не забыть восстановить предыдущую позицию указателя. Или воспользоваться fstat, как предложил eao197.

Да это я уже понял
В итоге реализовал следующим образом:
off_t o_tCurentPosition = lseek(fd, 0, SEEK_CUR);
off_t o_tResult = lseek(fd, 0, SEEK_END);
lseek(fd, o_tCurentPosition, SEEK_SET);
return o_tResult;


Ещё раз всем спасибо за советы
Re[5]: Как определить размер(длину) файла в Линукс средствам
От: Conr Россия  
Дата: 28.11.07 19:40
Оценка:
Здравствуйте, Dimitar, Вы писали:

D>В итоге реализовал следующим образом:

D>
D>off_t o_tCurentPosition = lseek(fd, 0, SEEK_CUR);
D>off_t o_tResult = lseek(fd, 0, SEEK_END);
D>lseek(fd, o_tCurentPosition, SEEK_SET);
D>return o_tResult;
D>


Все-таки очень советую переделать на fstat
    struct stat fs; 
    if( fstat(fd, &fs) != 0)
    { 
        <error hander>
    }

    return fs.st_size;

Бесполезное прыганье по файлу обычно ни к чему хорошему не приводит. Особенно если файлом окажется какой-нить non seekable device. На некоторых системах можно подхватить неплохую задержку, прежде чем lseek отвалится и сообщит об ошибке, а fstat отработает моментально.
Re: Как определить размер(длину) файла в Линукс средствами С
От: ilnar Россия  
Дата: 28.11.07 21:00
Оценка:
Здравствуйте, Dimitar, Вы писали:

D>Вопрос в следующем: чем под линуксом можно заменить функцию filelength(int fd)?

D>Более подробно: имеется написанная функция
D>
D>MyGetFileLength(int fd)
D>{
D>#ifdef WIN32
D>   return filelength(fd);
D>#elif defined UNIX_KERNEL
D>   return -1; // Вот сюда то и надо что-то поставить...
D>#endif
D>}
D>


тут уже высказались. нужен fstat.
функции аля seek тут, имхо, не к месту, хоть и решают задачу. но будет много жирных НО. начиная от не seekable нодов, заканчивая отсутствием прав на чтение, тогда как надо всего лишь получить атрибуты (не в rwx, а в дополнительных схемах управления правами)
Re[6]: Как определить размер(длину) файла в Линукс средствам
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 28.11.07 23:02
Оценка:
Здравствуйте, Conr, Вы писали:

C>Бесполезное прыганье по файлу обычно ни к чему хорошему не приводит. Особенно если файлом окажется какой-нить non seekable device. На некоторых системах можно подхватить неплохую задержку, прежде чем lseek отвалится и сообщит об ошибке, а fstat отработает моментально.


На не-seekable поле st_size вообще не будет иметь смысла, так что лучше вначале подумать, а вызывать ли что-то:) А явного признака seekable нет. В некоторых системах можно проверить st_mode на S_IFREG и S_IFBLK, но это непереносимо.

Впрочем, я уверен, что топикстартер (слово-то какое;)) ограничивается файлами на FS.
The God is real, unless declared integer.
Re[7]: Как определить размер(длину) файла в Линукс средствам
От: Conr Россия  
Дата: 28.11.07 23:53
Оценка:
Здравствуйте, netch80, Вы писали:

N>На не-seekable поле st_size вообще не будет иметь смысла, так что лучше вначале подумать, а вызывать ли что-то А явного признака seekable нет. В некоторых системах можно проверить st_mode на S_IFREG и S_IFBLK, но это непереносимо.

Вроде подобный код у меня всегда работал на Linux'ах всяких, Bsd и MacOSX А на какие системы это непереносимо? просто для общего развития...

if( (st.st_mode & S_IFMT) != S_IFREG )
{
   // non-seekable
}
else
{
  // st.st_size is valid
}
Re[8]: Как определить размер(длину) файла в Линукс средствам
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 29.11.07 04:33
Оценка: 10 (2)
Здравствуйте, Conr, Вы писали:

C>Вроде подобный код у меня всегда работал на Linux'ах всяких, Bsd и MacOSX :xz: А на какие системы это непереносимо? просто для общего развития...


C>if( (st.st_mode & S_IFMT) != S_IFREG )


Кстати, более рекомендуемый вариант — if(!S_ISREG(st.st_mode))

C>{

C> // non-seekable
C>}

Да файлы-то конечно seekable. Но кроме них ещё могут быть плоские диски и другие более странные объекты. Вот тут и начинается:

— традиционные юниксы: для каждого диска (раздела, слайса, etc.) есть блочное устройство (для монтирования) и байтовое (для ремонтов и дампов)
— FreeBSD: оставлено только байтовое ('c') устройство
— Linux: оставлено только блочное ('b') устройство

Проверка по st_mode на seekable, в таком случае, точнее всего в Linux (по условию S_ISREG(st.st_mode)||S_ISBLK(st.st_mode)). На всех прочих (с заменой S_ISBLK на S_ISCHR) она будет давать сильные сбои.
The God is real, unless declared integer.
Отредактировано 23.01.2016 13:41 netch80 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.