LINUX.ORG.RU

Размер файла в C.


0

1

Интересует то, как узнать сабж. Пока что есть такие мысли: можно юзать lseek(), fseek()+ftell() и семейство функций stat(). Нужно узнавать размер файла по его дескриптору. Интересует ещё такой вопрос: эти функции возвращают int, а если размер файла в будет больше 2147483647 байтов? Тогда как? Как обработать эту ситуацию?

★★★

Последнее исправление: Dorif (всего исправлений: 1)

stat возвращает не размер файла, а код ошибки (в успешном случае 0). Размер файла узнаётся в структуре, которая заполняется stat'ом, поле st_size типа off_t. off_t - беззнаковый, а вот какой у него точно размер - емнип от системы зависит

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Это я знаю. Но всё же интересуют ещё способы узнавания размера..

Dorif ★★★
() автор топика

эти функции возвращают int

Где вы такое прочитали?

man 2 lseek:

off_t lseek(int fd, off_t offset, int whence);
stat вообще размер файла не возвращает, а вместо этого заполняет структуру с информацией о файле:
struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               nlink_t   st_nlink;   /* number of hard links */
               uid_t     st_uid;     /* user ID of owner */
               gid_t     st_gid;     /* group ID of owner */
               dev_t     st_rdev;    /* device ID (if special file) */
               off_t     st_size;    /* total size, in bytes */
               blksize_t st_blksize; /* blocksize for file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };
Как видите, st_size имеет тип off_t, а размер off_t зависит от того, включена ли поддержка больших файлов при компиляции или нет, и он может быть > 32 бит:

Mixed sizes of off_t

During a period of transition from existing systems to systems able to support an arbitrarily large file size, most systems will need to support binaries with two or more sizes of the off_t data type (and related data types). This mixed off_t environment may occur on a system with an ABI that supports different sizes of off_t. It may occur on a system which has both a 64-bit and a 32-bit ABI.

Finally, it may occur when using a distributed system where clients and servers have differing sizes of off_t. In effect, the period of transition will not end until we need 128-bit file sizes, requiring yet another transition! The proposed changes may also be used as a model for the 64 to 128-bit file size transition.

http://www.unix.org/version2/whatsnew/lfs20mar.html#1.4

edigaryev ★★★★★
()
Ответ на: комментарий от yoghurt

off_t - беззнаковый

4.2. По дефолту это signed long. На 32-битных системах при указании «#define _FILE_OFFSET_BITS 64» будет signed long long.

Deleted
()

fseek/fteel принимают/возвращают off_t, stat возвращает структуру, которая тоже содержит off_t. Если платформа 32х битная, то надо использовать -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64

Reset ★★★★★
()
Ответ на: комментарий от edigaryev

>Где вы такое прочитали?

Упс, нужно быть внимательней :)

edigaryev ★★★★★
()
Ответ на: комментарий от Reset

fseek/fteel принимают/возвращают off_t

Кто вам такое сказал?

Deleted
()
Ответ на: комментарий от edigaryev

Значит я ошибся, ибо пользовался несколько неверной инфой. Кстати, если уж на то пошло: эта инфа из ISBN 978-5-94723-568-5 и K&R 2 издания(ей простительно- когда она издавалась двухгиговых файлов в планах не было.).

Dorif ★★★
() автор топика

а если размер файла в будет больше 2147483647 байтов? Тогда как? Как обработать эту ситуацию?

Проверять значение errno после вызова stat (или lseek):

RETURN VALUE
       On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

ERRORS
       EOVERFLOW
              (stat())  path  refers to a file whose size cannot be represented in the type off_t.  This can occur when an application compiled
              on a 32-bit platform without -D_FILE_OFFSET_BITS=64 calls stat() on a file whose size exceeds (2<<31)-1 bits.

edigaryev ★★★★★
()
Ответ на: комментарий от Reset

Т.е. просто вписать в код строчку #define _LARGEFILE64_SOURCE и #define _FILE_OFFSET_BITS=64 , объявить переменную в которой будет храниться размер файла как переменную типа off_t и это решит проблему?

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

Прочитайте же вы ман наконец! Если кратко: _LARGEFILE64_SOURCE не нужен, _FILE_OFFSET_BITS нужно писать первой строчкой в программе ПЕРЕД подключенем системных заголовочных файлов, в коде использовать функции, возвращающие off_t (например, fseeko/ftello вместо fseek/ftell), хранить размер файла в off_t.

Deleted
()
Ответ на: комментарий от Deleted

Почему _LARGEFILE64_SOURCE не нужен? И да, я(о ужас) не горю желанием перечитывать все маны ОС, у меня стоящей, ибо это займёт много времени, а вся информация всё равно не запомнится и в итоге я просто потрачу кучу времени вместо того, чтобы быстро и просто выполнить свою работу. А за совет про определение _FILE_OFFSET_BITS перед #include спасибо.

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

> И да, я(о ужас) не горю желанием перечитывать все маны ОС, у меня стоящей, ибо это займёт много времени, а вся информация всё равно не запомнится и в итоге я просто потрачу кучу времени вместо того, чтобы быстро и просто выполнить свою работу

Закрой редактор, удали gcc и никогда больше не трогай С - ты профнепригоден.

kemm
()
Ответ на: комментарий от anonymous

Спешу тебе рассказать- ты только что в первый раз зашёл на ЛОР, если не видел, как многие таким образом дописывают к своим комментам то, что пришло им в голову уже после их написания.

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

> А вы сами их все прочли?, прежде чем советы давать что и кому делать?)

Видишь ли, мой дорогой зелёный друг, я их читаю в случае необходимости - а не заявляю, что мол-де «мне работать нужно, а не документацию читать», после того, как тебя 15 раз послали сделать RTFM.

Именно поэтому ты непригоден даже на должность быдлокодеришки. Удали gcc и больше не трогай C.

kemm
()
Ответ на: комментарий от Dorif

А в этом случае сначала надо погуглить. Либо найдете сразу решение, либо прочитаете

man lseek64
...
       #define _LARGEFILE64_SOURCE
       #include <sys/types.h>
       #include <unistd.h>
...
Все там есть про нужный define.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Led

Воинствующие ламеры должны быть забанены

такъ победимъ!

jtootf ★★★★★
()
Ответ на: комментарий от Eddy_Em

Спасибо, но в моей Федоре мана про lseek64 нету(маны от tldp установлены).( Щас попробую на опеннете поискать. И на всякий случай: можете его текст сюда выложить?

Dorif ★★★
() автор топика
Ответ на: комментарий от Eddy_Em

нашёл ман на опеннете. Короткий и удобочитаемый. lseek64() можно не юзать, если вписать строчку #define _LARGEFILE64_SOURCE тогда стандартный lseek() тоже будет юзать 64-битный signed int(off64_t).

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

lseek64() можно не юзать, если вписать строчку #define _LARGEFILE64_SOURCE тогда стандартный lseek() тоже будет юзать 64-битный signed int(off64_t).

Именно об этом на протяжении всей темы вам и говорят.

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.