2012-06-26 7 views
7

Próbuję obliczyć rozmiary katalogów w sposób, który dzieli obciążenie, aby użytkownik mógł zobaczyć postęp zliczania. Myślałem, że logicznym sposobem na zrobienie tego byłoby najpierw stworzenie drzewa katalogów, a następnie wykonanie operacji liczącej długość wszystkich plików.Obliczanie rozmiarów katalogów

To, co mnie zaskakuje, polega na tym, że większość czasu (dysk/We/Wy) pochodzi z tworzenia drzewa katalogów, a następnie przejście przez FileInfo[] następuje prawie natychmiast bez praktycznie żadnego dysku I/O.

Próbowałem zarówno z Directory.GetDirectories(), po prostu tworząc drzewo ciągów nazw katalogów i przy użyciu obiektu DirectoryInfo, a obie metody nadal zajmują większość czasu I/O (czytanie oczywiście MFT) w porównaniu przechodzenie przez wszystkie pliki FileInfo.Length dla plików w każdym katalogu.

Domyślam się, że nie ma sposobu na zmniejszenie liczby operacji wejścia/wyjścia, aby drzewo było znaczące. Domyślam się, że po prostu zastanawiam się, dlaczego operacja ta zajmuje znacznie więcej czasu niż przejście do większej liczby plików?

Ponadto, jeśli ktokolwiek mógłby polecić nierekurencyjny sposób na sprawdzenie rzeczy (ponieważ wydaje mi się, że muszę po prostu podzielić wyliczenie i zrównoważyć je, aby rozmiar był bardziej responsywny). Zrobić wątek dla każdego podkatalogu poza bazą i pozwolić, by konkurencja w harmonogramie zrównoważyła to, co prawdopodobnie nie byłoby zbyt dobre, prawda?

EDIT: Repository for this code

+0

Mam również problem z obliczaniem rozmiaru katalogu. Zrobiłem dokładnie to, co zrobiłeś. Wypróbowane> fileInfo [], a następnie> Directory.GetDirectories(). Ale wciąż nie znam lepszego sposobu. –

+0

Mówisz, że wywoływanie GetDirectories() zajmuje dużo czasu? Nie widziałem tego, ale znowu, nigdy nie robiłem tego z dużą ilością katalogów. Poza tym, dlaczego miałbyś się przejmować jego rekurencją? Jest to rekursywne zadanie i nigdy nie będziesz mieć tylu zagnieżdżonych katalogów, że możesz wysadzić stos. –

+0

refer http://stackoverflow.com/questions/468119/whats-the-best-way-to-calculate-the-size-of-a-directory-in-net –

Odpowiedz

4

Można wykorzystać Parallel.ForEach uruchomić obliczenia wielkości katalogu w sposób równoległy. Możesz pobrać GetDirectories i uruchomić Parallel.ForEach na każdym węźle. Możesz użyć zmiennej, aby śledzić rozmiar i wyświetlać ją użytkownikowi. Każda równoległa kalkulacja będzie rosła na tej samej zmiennej. W razie potrzeby użyj blokady(), aby zsynchronizować wykonywanie równoległe.

+0

Powinieneś zakodować to tak, że tylko nie spokrewnione katalogi są zsynchronizowane i nie będzie żadnego powodu, aby blokować dalej.Chociaż w przypadku większości dysków nie jestem pewien, co zrównoważy cię. IO dyskowe wydają się z natury synchroniczne. Wszystko, co naprawdę możesz zrobić równolegle, to faktyczne dodanie sum, które powinno być pomijalne. –

+2

Możesz uzyskać równoległe IO z SSD ... –

+0

@JasonMalinowski Naprawdę ... Nie miałem pojęcia. Czy większość systemów operacyjnych wie, jak z tego skorzystać? Wiedziałem, że jest to znacznie szybsze ze względu na brak ruchomych części, nie miałem pojęcia, że ​​jest on również dostępny równolegle. –

Powiązane problemy