Какой самый быстрый / простой способ для подсчета большого количества файлов в каталоге (в 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 быстрее, чем.