Какой самый быстрый / простой способ для подсчета большого количества файлов в каталоге (в Linux)?
у меня был каталог с большим количеством файлов. Каждый раз, когда я пытался получить доступ к списку файлов внутри него, я не мог этого сделать или была значительная задержка. Я пытался использовать ls
команда в командной строке на Linux и веб-интерфейсе от моего хостинг-провайдера также не помогла.
проблема в том, что когда я просто делаю ls
требуется значительное количество времени, чтобы даже начать что-то показывать. Таким образом, ls | wc -l
не помогло бы также.
после некоторых исследований я придумал этот код (в данном примере он подсчитывает количество новых писем на сервере):
print sum([len(files) for (root, dirs, files) in walk('/home/myname/Maildir/new')])
приведенный выше код написан на Python. Я использовал инструмент командной строки Python, и он работал довольно быстро (результат возвращался мгновенно).
меня интересует ответ на следующий вопрос: Можно ли считать файлы в папке (без подпапок) быстрее? Как это сделать быстрее всего?
7 ответов
ls
тут stat(2)
вызова для каждого файла. Другие инструменты, как find(1)
и расширение подстановочного знака оболочки, может избежать этого вызова и просто сделать readdir
. Одна комбинация команд оболочки, которая может работать, -find dir -maxdepth 1|wc -l
, но он с удовольствием перечислит сам каталог и неправильно посчитает любое имя файла с новой строкой в нем.
от Python, прямой способ получить только эти имена -os.listdir(каталог). В отличие от ос.прогулка и ОС.путь.ходить, не нужно рекурсировать, проверьте типы файлов или выполните дальнейшие вызовы функций Python.
добавление: кажется, ls не всегда stat. По крайней мере, в моей системе GNU он может делать только вызов getdents, когда дополнительная информация (например, какие имена являются каталогами) не запрашивается. getdents-это базовый системный вызов, используемый для реализации readdir в GNU/Linux.
Addition 2: Одна из причин задержки перед результатами вывода ls заключается в том, что он сортирует и табулирует. ls-U1 может избежать этого.
общее количество файлов в заданной директории
find . -maxdepth 1 -type f | wc -l
общее количество файлов в данной директории и всех вложенных в нее
find . -type f | wc -l
для получения более подробной информации зайдите в терминал и сделайте man find
Это должно быть довольно быстро в Python:
from os import listdir
from os.path import isfile, join
directory = '/home/myname/Maildir/new'
print sum(1 for entry in listdir(directory) if isfile(join(directory,entry)))
Я думаю ls
тратит большую часть своего времени перед отображением первой строки, потому что он должен сортировать записи, поэтому ls -U
должен отображать первую строку намного быстрее (хотя в целом она может быть не намного лучше).
самый быстрый способ-избежать всех накладных расходов интерпретируемых языков и написать код, который непосредственно решает вашу проблему. Это трудно сделать переносным способом, но довольно просто. На данный момент я нахожусь на OS X box, но преобразование следующего в Linux должно быть чрезвычайно простым. (Я решил игнорировать скрытые файлы и считать только обычные файлы...при необходимости измените или добавьте параметры командной строки, чтобы получить необходимые функции.)
#include <dirent.h> #include <stdio.h> #include <stdlib.h> int main( int argc, char **argv ) { DIR *d; struct dirent *f; int count = 0; char *path = argv[ 1 ]; if( path == NULL ) { fprintf( stderr, "usage: %s path", argv[ 0 ]); exit( EXIT_FAILURE ); } d = opendir( path ); if( d == NULL ) { perror( path );exit( EXIT_FAILURE ); } while( ( f = readdir( d ) ) != NULL ) { if( f->d_name[ 0 ] != '.' && f->d_type == DT_REG ) count += 1; } printf( "%d\n", count ); return EXIT_SUCCESS; }
Я не уверен в скорости, но если вы хотите просто использовать встроенные оболочки, это должно работать:
#!/bin/sh
COUNT=0;
for file in /path/to/directory/*
do
COUNT=$(($COUNT+1));
done
echo $COUNT
мой вариант использования-это linux SBC (Banana Pi), подсчитывающий файлы в каталоге на USB-накопителе FAT32. В скорлупе, делая
ls -U {dir} | wc -l
занимает 6.4 сек с 32K файлами там (32k = max files / dir на FAT32) От python doing
t=time.time() ; print len(os.listdir(d)) ; print time.time()-t
занимает всего 0,874 секунды(!) Не вижу ничего в Python быстрее, чем.