Pobieranie plików z katalogu zawierającego dużą ilość plików

Mam katalog, który zawiera prawie 14,000,000 próbek audio w *.format wav.

Zwykły magazyn, bez podkatalogów.

Chcę przeglądać pliki w pętli, ale gdy używam DirectoryInfo.GetFiles() w tym folderze, cała aplikacja zawiesza się na kilka minut!

Czy można to zrobić w inny sposób? Może odczytać 1000, przetworzyć je, a następnie wziąć następne 1000 i tak dalej?
Author: Artjom B., 2011-10-23

6 answers

Czy próbowałeś EnumerateFiles metody klasy DirectoryInfo?

Jak mówi MSDN

Metody EnumerateFiles i GetFiles różnią się w następujący sposób: gdy użyj EnumerateFiles, możesz zacząć wyliczać zbiór FileInfo obiekty przed zwróceniem całej kolekcji; gdy użyj GetFiles, musisz poczekać aż cała tablica FileInfo obiektów zostanie zostanie zwrócona przed uzyskaniem dostępu do tablicy. Dlatego, gdy jesteś praca z wieloma plikami i katalogami, EnumerateFiles może be more wydajny.

 87
Author: Haris Hasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-23 08:47:59

W. NET 4.0, Directory.EnumerateFiles(...) jest IEnumerable<string> (zamiast string[] z Directory.GetFiles(...)), więc może streamować wpisy zamiast buforować je wszystkie; np.

foreach(var file in Directory.EnumerateFiles(path)) {
    // ...
}
 42
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-23 08:44:28

Uderzasz ograniczenie samego systemu plików Windows. Gdy liczba plików w katalogu rośnie do dużej liczby (a 14M przekracza ten próg), dostęp do katalogu staje się niewiarygodnie powolny. Nie ma znaczenia, czy czytasz jeden plik na raz, czy 1000, to tylko dostęp do katalogu.

Jednym ze sposobów rozwiązania tego problemu jest tworzenie podkatalogów i dzielenie plików na grupy. Jeśli każdy katalog ma 1000-5000 (zgaduję, ale można poeksperymentować z rzeczywistymi liczby), następnie należy uzyskać przyzwoitą wydajność otwierania/tworzenia / usuwania plików.

Dlatego, jeśli spojrzysz na aplikacje takie jak Doxygen, które tworzą plik dla każdej klasy, postępują zgodnie z tym schematem i umieszczają wszystko w 2 poziomach podkatalogów, które używają losowych nazw.

 17
Author: DXM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-23 08:42:25

Użyj funkcji Win32 Api FindFile, aby to zrobić bez blokowania aplikacji.

Można również wywołać Directory.GetFiles w systemie .Gwintowanie.Zadanie (TPL), aby zapobiec zamrożeniu interfejsu użytkownika.

 6
Author: Muhammad Hasan Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-23 08:41:03

Smacznego.

    public List<string> LoadPathToAllFiles(string pathToFolder, int numberOfFilesToReturn)
    {
        var DirInfo = new DirectoryInfo(pathToFolder);
        var firstFiles = DirInfo.EnumerateFiles().Take(numberOfFilesToReturn).ToList();
        return firstFiles.Select(l => l.FullName).ToList();
    }
 4
Author: Jaryn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 21:59:04

Często spotykam się z problemem dostępu do dużych plików w jednym katalogu. Podkatalogi są dobrym rozwiązaniem, ale wkrótce nawet nie oferują wiele pomocy czasami. To, co teraz robię, to tworzenie pliku indeksu - pliku tekstowego z nazwami wszystkich plików w katalogu (pod warunkiem, że tworzę pliki w tym katalogu). Następnie odczytuję plik indeksu, a następnie otwieram rzeczywisty plik z katalogu do przetworzenia

 3
Author: Faizul Hussain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-16 16:30:32