Выбор файла случайным образом из файловой системы - PullRequest
3 голосов
/ 02 сентября 2011

Этот вопрос относится к Имитация доступа к файловой системе .

Мне нужно выбрать файлы и каталоги случайным образом, чтобы они выступали в качестве аргументов файловых операций, таких как переименование, запись, чтение и т. Д. Я планировал сделать список всех файлов и каталогов с их путями и случайным образом выбрать из этого список. Но так как файлы и каталоги создаются и удаляются в реальной файловой системе, список также должен обновляться. Я считаю, что ведение списка и его обновление таким образом неэффективно, и оно также должно быть атомарным, чтобы более поздняя операция не обращалась к файлу, который был удален предыдущей операцией.

Можете ли вы предложить другой способ выбора файлов ... может быть, как-нибудь сделать это прямо из файловой системы ... но как тогда мы узнаем пути к файлам.

Спасибо

Я нашел здесь кое-что интересное Случайный выбор файла из дерева каталогов совершенно честным образом , особенно в Ответ Майкла Дж. Барбера, но я не смог полностью его понять из-за моего незнания питона

Ответы [ 3 ]

3 голосов
/ 02 сентября 2011

Вы не хотите пытаться поддерживать список файлов, когда файловая система прямо там. Вы должны быть в состоянии сделать это прямо из C. Идите из корневого каталога, выбирая из него случайный файл. Вы можете выбрать случайную максимальную глубину, и если вы нажмете обычный файл, в или до этого, используйте его. Если это каталог, повторите до максимальной глубины. Если это специальный файл, возможно, начните сначала.

Это должно быть довольно быстро. Операция не должна быть атомарной. Если файла нет, когда вы хотите выполнить свою операцию, попробуйте еще раз. Не должно быть слишком сложно. Вы можете создать путь, когда найдете целевой файл. Это будет проще, чем суетиться с fs напрямую (я полагаю, вы имели в виду на гораздо более низком уровне) и должно быть простым в реализации.

1 голос
/ 02 сентября 2011

Все, что вам нужно знать, - это сколько файлов в каждом каталоге, чтобы выбрать каталог, в который вы должны перейти. Избегайте обхода символических ссылок и подсчета файлов в символических ссылках.

Вы можете использовать решение, аналогичное описанному в pst.

Например, у вас есть 3 каталога, и в каждом есть 20,40 и 1000 файлов. Вы получаете всего [20,60,1060] и выбираете случайное число 0-1060. если это число больше или равно 60, вы переходите в третью папку.

Вы прекращаете обход, когда достигаете папок без папок.

Чтобы найти случайный файл по этому пути, вы можете применить тот же трюк, что и раньше.

Таким образом, вы выберете любой файл с равной вероятностью.

1 голос
/ 02 сентября 2011

Вот мое предлагаемое решение. Он не самый быстрый, но должен быть быстрым ( после подготовки ), использовать только скромную память и быть «достаточно хорошо распределенным». Это, конечно, на 100% непроверенный и несколько сложный (такой сложный, как поддержка дерева RB или подобного, в любом случае) - я жалко, что пришлось использовать C; -)

  1. Для каждого каталога в целевом домене создайте дерево каталогов, используя файловую систему с первым просмотром глубины, и запишите число файлов «до» (количество файлов, найденных на сегодняшний день, в дереве) и файл «после» количество (количество «до» плюс количество файлов в каталоге). Не следует хранить сами файлы. Быстрый способ узнать количество файлов приводит пример кода C. Это все еще требует итерации содержимого каталога, но не требует хранения самих файлов.

  2. Подсчитайте общее количество файлов в дереве. (Это должно быть просто счетчиком «после» последнего узла в дереве.)

  3. Выберите случайное число в диапазоне [0, максимальное количество файлов).

  4. Перейдите к узлу в дереве так, чтобы число файлов «до»

  5. Выберите случайный файл в каталоге, связанном с выбранным узлом - убедитесь, что вы снова посчитали каталог и используете его в качестве [0, limit] в выборе (с запасным вариантом в случае выгрузки) конец из-за проблем параллелизма). Если количество файлов изменилось, обязательно обновите дерево такой информацией. Также обновите / исправьте дерево, если каталог был удален и т. Д. (Дополнительный полный счет здесь не должен быть таким плохим, как кажется, так как readdir (в среднем) уже должен быть пройден через 1/2 записей в справочника. Однако следует изучить преимущества повторного подсчета, если таковые имеются.)

  6. При необходимости повторите шаги 2-5.

Периодически перестраивать все дерево (шаг № 1) для учета изменений в файловых системах. Удаление / добавление файлов будет медленно искажать случайность - шаг № 5 может помочь обновить дерево в определенных ситуациях. Частота восстановления должна быть определена путем экспериментов. Также возможно уменьшить вероятность появления ошибки, перестраивая родительские / прародительские узлы или [случайные] дочерние узлы при каждом проходе и т. Д. Использование измененного времени в качестве быстрого способа обнаружения изменений может также стоить изучить.

Счастливого кодирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...