Более быстрый (самый быстрый?) способ получить количество файлов в каталоге с более чем 200 000 файлов

Еще один модуль pypi, который включает в себя функцию печати python 3:

https://pypi.python.org/pypi/colorprint

Он применим в python 2.x если вы тоже from __future__ import print. Вот пример Python 2 со страницы Pypi для модулей:

from __future__ import print_function
from colorprint import *

print('Hello', 'world', color='blue', end='', sep=', ')
print('!', color='red', format=['bold', 'blink'])

Вывод «Hello, world!» со словами в синем и восклицательным знаком, выделенным красным и мигающим.

14
задан Richard Everett 28 July 2009 в 10:02
поделиться

9 ответов

Пространство имен System.IO.Directory не используется, нет. Вам нужно будет найти способ запроса каталога, который не требует создания огромного списка файлов.

Это похоже на небольшую оплошность со стороны Microsoft, API Win32 всегда имели функции, которые могли подсчитывать файлы в каталог.

Вы также можете рассмотреть возможность разделения вашего каталога. Я не понимаю, как вы управляете каталогом из 200 000 файлов: -)

Обновление:

Джон Сондерс поднимает хороший вопрос в комментариях. Мы уже знаем, что файловые системы (общего назначения) недостаточно приспособлены для работы с этим уровнем хранения. Одна вещь, которая оборудована для обработки огромного количества небольших «файлов», - это база данных.

Если вы можете определить ключ для каждого (содержащего, например, дату, час и номер клиента), эти файлы следует ввести в базу данных. Размер записи 4K и 108 миллионов строк (200 000 строк / день * 30 дней / месяц * 18 месяцев) должны легко обрабатываться большинством профессиональных баз данных. Я знаю, что DB2 / z пережевывает это на завтрак.

Затем, когда вам нужны некоторые тестовые данные, извлеченные в файлы, у вас есть сценарий / программа, которая просто извлекает соответствующие записи в файловую систему. Затем запустите тесты до успешного завершения и удалите файлы.

Это должно упростить решение вашей конкретной проблемы:

select count(*) from test_files where directory_name = '/SomeDirectory'

, конечно, при условии, что у вас есть индекс для directory_name.

Я знаю, что DB2 / z пережевывает это на завтрак.

Затем, когда вам нужны некоторые тестовые данные, извлеченные в файлы, у вас есть сценарий / программа, которая просто извлекает соответствующие записи в файловую систему. Затем запустите тесты до успешного завершения и удалите файлы.

Это должно упростить решение вашей конкретной проблемы:

select count(*) from test_files where directory_name = '/SomeDirectory'

, конечно, при условии, что у вас есть индекс для directory_name.

Я знаю, что DB2 / z пережевывает это на завтрак.

Затем, когда вам нужно извлечь некоторые тестовые данные в файлы, у вас есть сценарий / программа, которая просто извлекает соответствующие записи в файловую систему. Затем запустите тесты до успешного завершения и удалите файлы.

Это должно упростить решение вашей конкретной проблемы:

select count(*) from test_files where directory_name = '/SomeDirectory'

, конечно, при условии, что у вас есть индекс для directory_name.

4
ответ дан 1 December 2019 в 06:59
поделиться

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

Однако вы почти наверняка не найдете решений, которые работают намного быстрее, чем это.

Почему?

Элементы управления доступом.

Каждый файл в каталоге может иметь список управления доступом, что может помешать вам вообще увидеть файл.

Сама операционная система не может просто сказать: «Эй, есть 100 файлов. записи здесь, "потому что некоторые из них могут представлять файлы, о существовании которых вы не можете знать - их вообще не следует показывать . Таким образом, сама ОС должна перебирать файлы,

[Кстати, если вы хотите улучшить производительность каталога, содержащего много файлов, ограничьтесь строго 8,3 именами файлов. Нет, я не шучу - это быстрее, потому что ОС не должна сама генерировать имя файла 8.3, и потому что используемый алгоритм безумный. Попробуйте выполнить тест, и вы увидите.]

10
ответ дан 1 December 2019 в 06:59
поделиться

К вашему сведению, .NET 4 включает новый метод, Directory.EnumerateFiles , который делает именно то, что вам нужно - это здорово. Скорее всего, вы не используете .NET 4, но об этом все равно стоит помнить!

Изменить: Теперь я понимаю, что OP требовал ЧИСЛО файлов. Однако этот метод настолько полезен, что я сохраняю этот пост здесь.

Теперь я понимаю, что OP требовал ЧИСЛО файлов. Однако этот метод настолько полезен, что я сохраняю этот пост здесь.

Теперь я понимаю, что OP требовал ЧИСЛО файлов. Однако этот метод настолько полезен, что я сохраняю этот пост здесь.

8
ответ дан 1 December 2019 в 06:59
поделиться

Вы можете использовать System.Management и класс WMI «cim_datafile», просто выполните следующий запрос в WMI, вы также можете использовать Linq to Wmi но я не пробовал

select * from cim_datafile where drive='c:' and path='\\SomeDirectory\\' 

Думаю, будет быстрее

4
ответ дан 1 December 2019 в 06:59
поделиться

У меня была очень похожая проблема с каталогом, содержащим (мы думаем) ~ 300 000 файлов.

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

Мы сделали это, создав каталоги az , представляющие первую букву файла, затем подкаталоги для каждого из них, также содержащие az для второй буквы файла. . Затем мы вставили файлы в соответствующий каталог

, например,

gbp32.dat

вошли в

g/b/gbp32.dat

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

6
ответ дан 1 December 2019 в 06:59
поделиться

Если вы не боитесь вызывать функции win32, возможно, стоит попробовать FIndFirstFile , а затем выполнить итерацию с помощью FindNextFile . Это экономит накладные расходы на выделение всех этих строк только для подсчета.

3
ответ дан 1 December 2019 в 06:59
поделиться

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

4
ответ дан 1 December 2019 в 06:59
поделиться

Создавать индекс каждый день в полночь. Тогда поиск файла будет происходить очень быстро. И подсчет количества файлов столь же тривиален.

Если я правильно понимаю, у вас есть один каталог на каждый день. Если все файлы, которые вы получаете сегодня, попадут на карту сегодняшнего дня, то эту систему можно улучшить. Просто проиндексируйте каталог предыдущего дня в полночь.

1
ответ дан 1 December 2019 в 06:59
поделиться

Если я использую медленный язык высокого уровня и переносимость не является большой проблемой, у меня возникнет соблазн попробовать вызвать внешнюю программу (например, `ls | wc`.first.to_i при использовании ruby ​​и unix), но потом я бы проверил, работает ли он лучше.

0
ответ дан 1 December 2019 в 06:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: