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!
6 answers
Czy próbowałeś EnumerateFiles metody klasy DirectoryInfo?
Jak mówi MSDN
Metody
EnumerateFiles
iGetFiles
różnią się w następujący sposób: gdy użyjEnumerateFiles
, możesz zacząć wyliczać zbiórFileInfo
obiekty przed zwróceniem całej kolekcji; gdy użyjGetFiles
, musisz poczekać aż cała tablicaFileInfo
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.
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)) {
// ...
}
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.
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.
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();
}
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
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