Возможен ввод-вывод 2-го уровня в Linux с использованием readdir()?

#linux #readdir

#linux #readdir

Вопрос:

Я пытаюсь обойти структуру каталогов и открыть каждый файл в этой структуре. Для обхода я использую opendir() и readdir(). Поскольку у меня уже есть объект, кажется глупым создавать путь и открывать файл — это, по-видимому, заставляет Linux находить каталог и файл, которые я только что пересек.

Для ввода-вывода 2-го уровня (открытие, создание, чтение, запись) требуется путь. Есть ли какой-либо вызов, чтобы либо открыть имя файла внутри каталога, либо открыть файл с заданным индексом?

Комментарии:

1. «это, по-видимому, заставляет Linux находить каталог и файл, которые я только что пересек». — Я бы немного покопался / измерил, чтобы понять, стоит ли это пытаться оптимизировать. Ваше предположение здесь может быть неверным.

2. Если ничего другого, это заставляет меня создавать path, когда я этого не хочу!

3. Существует (довольно новый) системный вызов openat(). Однако от opendir() / readdir() мало что можно получить для передачи в вызов openat().

Ответ №1:

Вероятно, вам следует использовать nftw (3) для рекурсивного обхода файлового дерева.

В противном случае, переносимым способом, создайте свой каталог путь к имени файла, используя, например

 snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dirname, filename);
  

(или, возможно, с использованием asprintf(3), но не забудьте позже free сообщить результат)

И чтобы ответить на ваш вопрос об открытии файла в каталоге, вы могли бы использовать Linux или POSIX2008, или POSIX2008(2). Но я считаю, что вам действительно следует использовать nftw или сконструировать свой путь, как предложено выше. Прочитайте также о O_PATH и O_TMPFILE в open(2).

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

Даже не думайте открывать файл по номеру его индекса: это нарушит несколько абстракций файловой системы! (но это вряд ли возможно из-за безумных и отвратительных трюков, например debugfs — и это, вероятно, может очень сильно повредить вашей файловой системе !!).

Помните, что файлы обычно представляют собой индексы и могут иметь нулевое ( open затем процесс разорвал связь (2) с файлом, сохранив дескриптор открытого файла), одно (это обычный случай) или несколько (например, /foo/bar1 и /gee/bar2 могут быть жестко связаны с помощью ссылки (2) ….) имен файлов.

Некоторые файловые системы (например, FAT …) не имеют реальных индексов. В этом случае ядро что-то подделывает.

Комментарии:

1. openat — это именно то, что я искал, но почему постоянное восстановление пути к строке лучше?

2. Потому что openat это может быть неработоспособно или недоступно не на каждом ядре или файловой системе. Построение строки намного быстрее — поэтому незначительно — чем вызов системных вызовов файловой системы (которые, по крайней мере, обращаются к кешу файловой системы и, возможно, даже к диску).