Автор Тема: Как получить размер файла для файла 4Гб и больше (stat)? [решено]  (Прочитано 3733 раз)

Оффлайн Merblud

  • Давно тут
  • **
  • Сообщений: 460
Alt Linux 4.2.
В проге надо обрабатывать размер файла. Вызывается stat и без особых изысков читается поле st_size структуры stat. Для файлов в районе 4 Гб получается ерунда. Хотя тот же ls показывает все корректно, да и Конкуерор тоже.
Куда смотреть, чего копать? Подскажите.
В OpenSUSE абсолютно тот же код работает без проблем. Правда она 64-битная. Но к сожалению ничего 32-битного больше под рукой нет.
« Последнее редактирование: 22.04.2009 19:02:38 от Skull »

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 246
  • Учиться .... Телепатами не рождаются, ими ....
    • Email
Посмотрите код того-же ls

Alexei_VM

  • Гость
Куда смотреть, чего копать? Подскажите.

Смотреть, очевидно, в Гугл, который, после 5 минут стараний, говорит, что
http://www.delorie.com/gnu/docs/glibc/libc_285.html


Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 246
  • Учиться .... Телепатами не рождаются, ими ....
    • Email
man stat

  struct stat {
                  dev_t         st_dev;      /* устройство */
                  ino_t         st_ino;      /* inode */
                  mode_t        st_mode;     /* режим доступа */
                  nlink_t       st_nlink;    /* количество жестких ссылок */
                  uid_t         st_uid;      /* ID пользователя-владельца */
                  gid_t         st_gid;      /* ID группы-владельца */
                  dev_t         st_rdev;     /* тип устройства */
                                             /* (если это устройство) */
                  off_t         st_size;     /* общий размер в байтах */
                  unsigned long st_blksize;  /* размер блока ввода-вывода */
                                             /* в файловой системе */
                  unsigned long st_blocks;   /* количество выделенных блоков */
                  time_t        st_atime;    /* время последнего доступа */
                  time_t        st_mtime;    /* время последней модификации */
                  time_t        st_ctime;    /* время последнего изменения */
              };

off_t
http://www.linux.org.ru/view-message.jsp?msgid=3628699&lastmod=1239709563415

Цитировать
Всем спасибо, нашёл таки :)
 glibc
 FILE * fopen64 (const char *filename, const char *opentype)
 off64_t ftello64 (FILE *stream)

Оффлайн Andrey

  • Завсегдатай
  • *
  • Сообщений: 734

Оффлайн Merblud

  • Давно тут
  • **
  • Сообщений: 460
Куда смотреть, чего копать? Подскажите.

Смотреть, очевидно, в Гугл, который, после 5 минут стараний, говорит, что
http://www.delorie.com/gnu/docs/glibc/libc_285.html


Ну _FILE_OFFSET_BITS == 64 оказывает некоторое действие. К сожалению только размер правильным не получается.


Оффлайн Merblud

  • Давно тут
  • **
  • Сообщений: 460
man stat

  struct stat {
                  dev_t         st_dev;      /* устройство */
                  ino_t         st_ino;      /* inode */
                  mode_t        st_mode;     /* режим доступа */
                  nlink_t       st_nlink;    /* количество жестких ссылок */
                  uid_t         st_uid;      /* ID пользователя-владельца */
                  gid_t         st_gid;      /* ID группы-владельца */
                  dev_t         st_rdev;     /* тип устройства */
                                             /* (если это устройство) */
                  off_t         st_size;     /* общий размер в байтах */
                  unsigned long st_blksize;  /* размер блока ввода-вывода */
                                             /* в файловой системе */
                  unsigned long st_blocks;   /* количество выделенных блоков */
                  time_t        st_atime;    /* время последнего доступа */
                  time_t        st_mtime;    /* время последней модификации */
                  time_t        st_ctime;    /* время последнего изменения */
              };

off_t
http://www.linux.org.ru/view-message.jsp?msgid=3628699&lastmod=1239709563415

Цитировать
Всем спасибо, нашёл таки :)
 glibc
 FILE * fopen64 (const char *filename, const char *opentype)
 off64_t ftello64 (FILE *stream)

Это тоже попробовал. Нет результата. Разве что в спешке в чем-нибудь ошибся.

Оффлайн Merblud

  • Давно тут
  • **
  • Сообщений: 460
Alt Linux 4.2.
Дайте скачать!!

Ну апшибся я со второй циферкой. :)

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 246
  • Учиться .... Телепатами не рождаются, ими ....
    • Email
size(off_t) у вас чему равен ?

Alexei_VM

  • Гость
Все работает. Если уметь готовить :). Или хотеть уметь готовить.

Берем простой код:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

struct stat buf32;

int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("Usage: prog /path/to/file\n");
return -1;
};

if (stat(argv[1], &buf32) == -1)
{
           perror("stat");
           exit(EXIT_SUCCESS);
        };
printf("File name: %s\n", argv[1]);
printf("Filesize (32bit): %lld\n", (long long) buf32.st_size);


return 0;
};


Собираем, запускаем:
[alexei@threebears filesize]$ gcc ./filesize.c
[alexei@threebears filesize]$ ./a.out /ALT/Distrib/ISO/GAMES/lc-games-dvd.iso
stat: Value too large for defined data type

Не работает. Говорим "хм..." и лукаво смотрим:
[alexei@threebears filesize]$ gcc ./filesize.c -D_FILE_OFFSET_BITS=64
[alexei@threebears filesize]$ ./a.out /ALT/Distrib/ISO/GAMES/lc-games-dvd.iso
File name: /ALT/Distrib/ISO/GAMES/lc-games-dvd.iso
Filesize (32bit): 4417155072

« Последнее редактирование: 22.04.2009 23:31:30 от Alexei_VM »

Оффлайн Merblud

  • Давно тут
  • **
  • Сообщений: 460
Все работает. Если уметь готовить :). Или хотеть уметь готовить.

Берем простой код:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

struct stat buf32;

int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("Usage: prog /path/to/file\n");
return -1;
};

if (stat(argv[1], &buf32) == -1)
{
           perror("stat");
           exit(EXIT_SUCCESS);
        };
printf("File name: %s\n", argv[1]);
printf("Filesize (32bit): %lld\n", (long long) buf32.st_size);


return 0;
};


Собираем, запускаем:
[alexei@threebears filesize]$ gcc ./filesize.c
[alexei@threebears filesize]$ ./a.out /ALT/Distrib/ISO/GAMES/lc-games-dvd.iso
stat: Value too large for defined data type

Не работает. Говорим "хм..." и лукаво смотрим:
[alexei@threebears filesize]$ gcc ./filesize.c -D_FILE_OFFSET_BITS=64
[alexei@threebears filesize]$ ./a.out /ALT/Distrib/ISO/GAMES/lc-games-dvd.iso
File name: /ALT/Distrib/ISO/GAMES/lc-games-dvd.iso
Filesize (32bit): 4417155072



Спасибо. Все именно так и делал. Только в тесте забыл в printf-е указать формат вывода для 64 бит.  :)

Alexei_VM

  • Гость
Спасибо. Все именно так и делал. Только в тесте забыл в printf-е указать формат вывода для 64 бит.  :)

Между прочим, мой код основан на содержимом man stat64. Если бы вы сами заглянули в него, вопрос решился бы гораздо быстрее.

Оффлайн Merblud

  • Давно тут
  • **
  • Сообщений: 460
Спасибо. Все именно так и делал. Только в тесте забыл в printf-е указать формат вывода для 64 бит.  :)

Между прочим, мой код основан на содержимом man stat64. Если бы вы сами заглянули в него, вопрос решился бы гораздо быстрее.

С чего вы взяли, что я туда не заглядывал. Просто не обращал внимание на нужное в данном случае место.