stat () - это системный вызов Unix, который возвращает атрибуты файла для индексного дескриптора . Семантика stat () различается в зависимости от операционной системы . Например,команда ls в Unix использует этот системный вызов для получения информации о файлах, которая включает:
- atime: время последнего доступа ( ls -lu )
- mtime: время последней модификации ( ls -l )
- ctime: время последнего изменения статуса ( ls -lc )
stat
появился в версии 1 Unix . Это один из немногих оригинальных системных вызовов Unix, которые необходимо изменить, с добавлением в Версии 4 групповых разрешений и большего размера файла . [1]
stat () функции
С POSIX библиотека заголовка sys / stat.h , найденный в POSIX и других Unix-подобных операционных системах, объявляет stat()
функции, а также связанные с ними функции, называемые fstat()
и lstat()
. Функции принимают struct stat
аргумент буфера, который используется для возврата атрибутов файла. В случае успеха функции возвращают ноль, а в случае ошибки возвращается -1, а значение errno устанавливается соответствующим образом.
Функции stat()
и lstat()
принимают аргумент имени файла . Если файл является символической ссылкой , stat()
возвращает атрибуты конечной цели ссылки, а lstat()
возвращает атрибуты самой ссылки. fstat()
Функция принимает дескриптор файла аргумент вместо этого, и возвращает атрибуты файла , который он идентифицирует.
Семейство функций было расширено для реализации поддержки больших файлов . Функции по имени stat64()
, lstat64()
и fstat64()
возвращаемые атрибутов в struct stat64
структуре, которая представляет размер файла с типом 64-битным, позволяя функции для работы с файлами 2 Гб и больше (до 8 EIB). Когда _FILE_OFFSET_BITS
макрос определен как 64, эти 64-битные функции доступны под исходными именами.
Функции определены как:
int stat ( const char * filename , struct stat * buf ); int lstat ( const char * filename , struct stat * buf ); int fstat ( int filedesc , struct stat * buf );
структура статистики
Эта структура определена в sys / stat.h, как показано ниже, хотя реализации могут определять дополнительные поля: [2]
struct stat { mode_t st_mode ; ino_t st_ino ; dev_t st_dev ; dev_t st_rdev ; nlink_t st_nlink ; uid_t st_uid ; gid_t st_gid ; off_t st_size ; struct timespec st_atim ; struct timespec st_mtim ; struct timespec st_ctim ; blksize_t st_blksize ; blkcnt_t st_blocks ; };
POSIX.1 не требует st_rdev
, st_blocks
и st_blksize
членов; эти поля определены как часть опции XSI в спецификации Single Unix.
В более старых версиях стандарта POSIX.1 поля, связанные со временем, определялись как st_atime
, st_mtime
и st_ctime
, и имели тип time_t
. С версией стандарта 2008, эти поля были переименованы в st_atim
, st_mtim
и st_ctim
, соответственно, типе структуры timespec
, так как эта структура обеспечивает более высокое разрешение единицу времени. Для совместимости реализации могут определять старые имена в терминах tv_sec
члена struct timespec
. Например, st_atime
можно определить как st_atim.tv_sec
. [2]
В struct stat
состав входят как минимум следующие члены:
st_dev
- идентификатор устройства, содержащего файлst_ino
- номер inodest_mode
- режим защиты ; см. также разрешения Unixst_nlink
- количество ссылок на жестких ссылокst_uid
- идентификатор пользователя владельцаst_gid
- групповой идентификатор владельцаst_rdev
- идентификатор устройства (если специальный файл )st_size
- общий размер файла в байтахst_atime
- время последнего доступаst_mtime
- время последней модификацииst_ctime
- время последнего изменения статусаst_blksize
- предпочтительный размер блока для ввода-вывода файловой системы, который может зависеть как от системы, так и от типа файловой системы [3]st_blocks
- количество выделенных блоков кратноDEV_BSIZE
(обычно 512 байт).
st_mode
Поле представляет собой битовое поле . Он сочетает в себе режимы доступа к файлам, а также указывает любой специальный тип файла . Есть много макросов для работы с разными флагами режима и типами файлов.
Критика времени
Чтение файла меняет его время, в конечном итоге требующее записи на диск , что подвергалось критике за несовместимость с файловой системой только для чтения. Кэш файловой системы может значительно сократить эту активность до одной записи на диск за очистку кеша.
Разработчик ядра Linux Инго Мольнар публично раскритиковал концепцию и влияние atime на производительность в 2007 г. [4] [5], а в 2009 г. Параметр монтирования relatime стал параметром по умолчанию, который устраняет эту критику. [6] Поведение, стоящее за Параметр монтирования relatime обеспечивает достаточную производительность для большинства целей и не должен нарушать работу каких-либо значительных приложений, поскольку он подробно обсуждался. [7] Первоначально relatime обновляет atime, только если atime
Текущие версии ядра Linux поддерживают четыре варианта монтирования, которые можно указать в fstab :
- strictatime (ранее atime , а ранее по умолчанию; strictatime с версии 2.6.30) - всегда обновлять время, которое соответствует поведению, определенному POSIX
- relatime («относительное время», введенное в 2.6.20 и значение по умолчанию с 2.6.30) - обновлять время только при определенных обстоятельствах: если предыдущее время старше, чем mtime или ctime, или предыдущее время превышает 24 часа в прошлое
- nodiratime - никогда не обновлять время каталогов, но обновлять время других файлов
- noatime - никогда не обновлять время любого файла или каталога; подразумевает nodiratime ; высочайшая производительность, но наименее совместимая
- lazytime - обновить время в соответствии с конкретными обстоятельствами, изложенными ниже
Текущие версии Linux , macOS , Solaris , FreeBSD и NetBSD поддерживают Параметр монтирования noatime в / etc / fstab , из-за которого поле atime никогда не обновляется. Отключение обновления atime нарушает совместимость с POSIX и некоторые приложения, такие как mbox- управляемые уведомления о «новой почте » [9] и некоторые утилиты для отслеживания использования файлов, в частности tmpwatch .
В Параметр noatime в OpenBSD больше похож на Linux relatime . [10]
Версия 4.0 основной ветки ядра Linux , выпущенная 12 апреля 2015 года, представила новую опцию монтирования. ленивое время . Он позволяет выполнять обновления atime в стиле POSIX в памяти и сбрасывать их на диск вместе с некоторыми операциями ввода-вывода, не связанными со временем, в том же файле; Временные обновления также сбрасываются на диск при выполнении некоторых системных вызовов синхронизации или до того, как индексный дескриптор файла в памяти будет удален из кеша файловой системы. Кроме того, можно настроить, как долго изменения могут оставаться не сброшенными. Таким образом, lazytime сохраняет совместимость с POSIX, предлагая при этом улучшения производительности. [11] [12]
ctime
Заманчиво полагать, что ctime изначально означало время создания; [13] однако, в то время как ранний Unix имел время модификации и создания, последнее было изменено на время доступа до того, как появилась какая-либо структура C, в которой можно было бы вызывать ctime . Файловые системы сохранили только время доступа ( atime ) и время модификации ( mtime ) через 6-е издание Unix. В Временная метка ctime была добавлена при реструктуризации файловой системы, которая произошла в 7-й редакции Unix, и всегда относилась ко времени изменения inode. Он обновляется любое время файла метаданные , хранящиеся в изменении индексных дескрипторов, такие как права доступа к файлам , права собственности файлов и создание и удаление жестких ссылок , В некоторых реализациях ctime зависит от переименования файла: оба оригинальных Unix, которые реализовали переименование путем создания ссылки (обновление ctime ), а затем отключение старого имени (обновление ctime снова), и современный Linux склонен делать это.
в отличие время и mtime , ctime не может быть установлено произвольное значение с помощью utime () , используемый Touch , например. Вместо этого, когда utime () или для любых других изменений inode, кроме обновления время, вызванное доступом к файлу, ctime установлено текущее время.
Детализация по времени
- time_t показывает время с точностью до одной секунды.
- Некоторые файловые системы обеспечивают более тонкую детализацию. Solaris 2.1 введен микросекундный с УФС в 1992 году [ править ] и наносекундное разрешение с файловой системой ZFS. [ необходима цитата ]
- В ядрах Linux 2.5.48 и выше структура stat поддерживает наносекундное разрешение для трех полей метки времени файла. Они отображаются как дополнительные поля в структуре статистики. [14] [15]
- Разрешение времени создания в файловой системе FAT составляет 10 миллисекунд, в то время как разрешение времени записи составляет две секунды, а время доступа имеет разрешение один день, поэтому оно действует как дата доступа. [16]
Пример
#include #include #include #include #include #include #include int main ( int argc , char * argv []) {struct stat sb ; struct passwd * pwuser ; struct group * grpnam ;if ( argc < 2 ) { fprintf ( stderr , "Использование:% s: файл ... \ n " , argv [ 0 ]); выход ( EXIT_FAILURE ); }for ( int i = 1 ; i < argc ; i ++ ) { если ( -1 == stat ( argv [ i ], & sb )) { perror ( "stat ()" ); выход ( EXIT_FAILURE ); }если ( NULL == ( pwuser = getpwuid ( sb . st_uid ))) { perror ( "getpwuid ()" ); выход ( EXIT_FAILURE ); }если ( NULL == ( grpnam = getgrgid ( sb . st_gid ))) { perror ( "getgrgid ()" ); выход ( EXIT_FAILURE ); }printf ( "% s: \ n " , argv [ i ]); printf ( " \ t индекс:% u \ n " , сб . st_ino ); printf ( " \ t владелец:% u (% s) \ n " , sb . st_uid , pwuser -> pw_name ); printf ( " \ t группа:% u (% s) \ n " , sb . st_gid , grpnam -> gr_name ); printf ( " \ t допуск:% o \ n " , сб . st_mode & ( S_IRWXU | S_IRWXG | S_IRWXO )); printf ( " \ t ссылки:% d \ n " , сб . st_nlink ); printf ( " \ t размер:% ld \ n " , сб . st_size ); / * вы можете использовать% lld * / printf ( " \ t atime:% s" , ctime ( & sb . st_atim . tv_sec )); printf ( " \ t mtime:% s" , ctime ( & sb . st_mtim . tv_sec )); printf ( " \ t ctime:% s" , ctime ( & sb . st_ctim . tv_sec ));printf ( " \ п " ); }возврат 0 ; }
Рекомендации
- Перейти ↑ McIlroy, MD (1987). Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (технический отчет). CSTR. Bell Labs. 139.
- ^ a b Стивенс и Раго 2013 , стр. 94.
- ^ "" . Открытая группа Базовые характеристики Выпуск 6-IEEE Std 1003.1, 2004 Edition , . Открытая группа. 2004 г.
- ^ Ловушка ядра: Linux: замена atime на relatime , Джереми, 7 августа 2007 г.
- ↑ Однажды , LWN, Джонатан Корбет, 8 августа 2007 г.
- ^ Ядро Linux 2.6.30 , новички в ядре Linux
- ^ Этот массивный поток файловой системы , LWN, Джонатан Корбет, 31 марта 2009 г.
- ^ Relatime Recap , Валери Аврора
- ^ http://www.mail-archive.com/[email protected]/msg24912.html "$ MAIL-монитор оболочки ... зависит от времени, произнося новое электронное письмо с помощью atime ($ MAIL)
- ^ "mount (2) - страницы руководства OpenBSD" . openbsd.org . 27 апреля 2018 . Проверено 26 сентября 2018 года .
- ^ «Ядро Linux 4.0, раздел 1.5. Параметр lazytime для лучшего обновления временных меток файлов» . kernelnewbies.org . 1 мая 2015 года . Проверено 2 мая 2015 года .
- ^ Джонатан Корбет (19 ноября 2014 г.). «Представляем ленивое время» . LWN.net . Проверено 2 мая 2015 года .
- ^ https://www.bell-labs.com/usr/dmr/www/cacm.html
- ^ "stat (2) - справочная страница Linux" . man7.org . Проверено 27 февраля 2015 года .
- ^ Андреас Джагер (2 декабря 2002 г.), struct stat.h с наносекундным разрешением , почтовый архив списка рассылки [email protected] для проекта glibc.
- ^ MSDN: время файла
- IEEE Std 1003.1, 2004, документация для fstat (2) . Проверено 7 июня 2012.
- stat (2) Справочная страница Linux . Проверено 7 июня 2012.
- У. Ричард, Стивенс; Стивен А., Раго (24 мая 2013 г.). Расширенное программирование в среде UNIX (Третье изд.). Эддисон-Уэсли Профессионал . ISBN 978-0321637734. Проверено 27 февраля 2015 года .
Внешние ссылки
- Пример, показывающий, как использовать stat ()
- stat () в Perl
- stat () в PHP
- время и относительность