Альтернативы использованию stat () для получения типа файла? - PullRequest
1 голос
/ 01 апреля 2010

Есть ли альтернативы stat (который встречается в большинстве систем Unix), который может определять тип файла? На странице руководства написано, что вызов stat стоит дорого, и мне нужно вызывать его довольно часто в моем приложении.

Ответы [ 5 ]

7 голосов
/ 01 апреля 2010

Альтернатива - fstat(), если у вас уже открыт файл (поэтому у вас есть дескриптор файла для него). Или lstat(), если вы хотите узнать о символических ссылках, а не о файле, на который указывает символическая ссылка.

Я думаю, что страница справочника преувеличивает стоимость; это не намного хуже, чем любой другой системный вызов, который должен преобразовать имя файла в индекс. Это дороже, чем getpid(); это дешевле, чем open().

3 голосов
/ 01 апреля 2010

«Тип файла», который дает stat(), это то, является ли файл обычным файлом или чем-то вроде файла устройства или каталога, среди прочего, например, его размер и номер инода. Если это то, что вам нужно знать, тогда вы должны использовать stat().

Если вам нужно знать тип файла , например, файл. текстовый файл, изображение JPEG, аудио MP3 - тогда у вас есть два варианта. Вы можете угадать, основываясь на расширении имени файла (если оно заканчивается на «.mp3», файл, вероятно, содержит аудио MP3), или вы можете использовать libmagic , который фактически открывает файл и считывает часть его содержимого в выяснить, что это такое. Подход libmagic более дорогой (если вы пытаетесь избежать stat(), вы, вероятно, тоже хотите избегать open()), но менее подвержен ошибкам (в случае, если файл ".mp3" на самом деле является изображением JPEG, для пример).

2 голосов
/ 02 апреля 2010

В Linux с некоторыми файловыми системами тип файла (обычный, устройство char, блочное устройство, каталог, канал, ссылка sym, ...) хранится в структуре linux_dirent, в которую ядро ​​передает записи каталога приложений через системный вызов getdents. Если единственной вещью в структуре статистики, в которой вы нуждались, был тип файла, и вам нужно было получить его для всех или многих записей каталога, вы можете использовать getdents напрямую (а не readdir) и попытаться получить тип файла из этого, только используя stat, если вы нашли неверный тип файла в linux_dirent. В зависимости от модели использования файловой системы вашего приложения это может быть быстрее, чем использование stat, если вы используете Linux, но во многих случаях stat должен быть быстрым.

Скорость Stat в основном связана с поиском запрашиваемых данных на диске. Если вы просматриваете каталог с рекурсивной статистикой всех файлов, то каждая статистика должна в целом быть довольно быстрой, потому что большая часть работы по получению данных статистики заканчивается кэшированием перед тем, как вы запросите ядро ​​для этого при предыдущем вызове stat , С другой стороны, если вы регистрируете одинаковое количество файлов, случайно распределенных по системе, ядру, вероятно, придется считывать с диска несколько каталогов для каждого файла, для которого вы собираетесь вызывать stat.

fstat всегда должен быть очень быстрым, поскольку ядро ​​уже должно иметь данные, которые вы запрашиваете в оперативной памяти, так как ему необходим доступ к нему, чтобы файл находился в открытом состоянии, и ядру не нужно было идти из-за проблем с обходом пути к имени файла, чтобы увидеть, находится ли каждый компонент в оперативной памяти или на диске, и, возможно, для чтения в каталоге с диска (но, вероятно, не нужно), только чтобы обнаружить, что он содержит данные, которые вы запрашиваете в оперативной памяти.

При этом вызов stat для открытого файла должен быть быстрее, чем вызов для неоткрытого файла.

1 голос
/ 21 января 2011

Если ваше приложение должно работать в системах Linux, почему бы вам не попробовать inotify (7). Это определенно быстрее, чем stat много файлов.

1 голос
/ 01 апреля 2010

Вам известен "волшебный" файл в * nix системах? Запрашивая файл из командной строки, например file myfile.ext, вы можете получить реальный тип файла.

Это делается путем чтения содержимого файла, а не просмотра его расширения, и широко используется в * nix (Linux, Unix, ...) системах.

...