2009-12-28 17 views
5

Ecco il codice che sto utilizzando:C aiuto della memoria # directory.getfiles

using (StreamWriter output = new StreamWriter(Path.Combine(masterdestination, "Master.txt"))) 
{ 
    string masterfolders = sourcefolder1; 
    string[] filess = Directory.GetFiles(masterfolders, "*.txt"); 
    foreach (string file in filess) 
    { 
     output.WriteLine(Path.GetFileName(file)); 
    } 
} 

Questo codice cercherà tutti i file in una directory specificata dall'utente per qualsiasi file txt. Queste directory contengono talvolta 2 milioni di file.

monitoraggio di questo processo mentre è in esecuzione ho visto salire fino a 800 MB di utilizzo della memoria. C'è un modo per preservare la velocità di questo processo e limitare la memoria che utilizza? O leggere e scaricare e continuare? Hashtable? Qualsiasi idea sarebbe fantastica.

+0

800K? Intendevi 800 MB? –

+1

Perché 1mb di utilizzo della memoria è un problema?Oltre un milione di file? –

+0

800 megs è quello che ho –

risposta

14

Directory.GetFiles fa davvero schifo. Se è possibile utilizzare .NET 4.0, è necessario esaminare Directory.EnumerateFiles. Dalla documentazione:

Le EnumerateFiles e GetFiles metodi differiscono nel modo seguente: Quando si uso EnumerateFiles, è possibile avviare enumerare la raccolta dei nomi prima che l'intera collezione è restituito; quando si utilizza GetFiles, è necessario attendere per l'intero array di nomi prima di poter accedere alla matrice . Pertanto, quando si è che funziona con molti file e le directory , EnumerateFiles può essere più efficiente.

+0

Non avevo idea che stessero aggiungendo questo. Bello! – BFree

+0

@ BFree- È sicuramente più bello! È una delle cose in .NET 4.0 non vedo l'ora! – RichardOD

+0

Credo che l'implementazione mono di .Net abbia anche questo, quindi è possibile utilizzare le librerie mono per iterare sui file se .Net 4 non è un'opzione. –

0

Come accennato nella risposta here se si utilizza .NET 4.0, è possibile utilizzare il metodo EnumerateFiles statico sulla classe Directory per ottenere un posto di IEnumerable<string> una stringa [], che sta portando a tutto il consumo di memoria.

Se si sta lavorando con una versione di .NET precedente a .NET 4.0, è possibile simulare facilmente questa funzionalità chiamando i metodi FindFirstFileEx, FindNextFile, etc, etc, attraverso il livello P/Invoke.

Quindi, per ogni file restituito da una chiamata a FindFirstFile/FindNextFile si restituirà l'articolo.

Questo riduce il consumo di memoria come EnumerateFiles farebbe per le directory con un numero elevato di file perché non li si carica tutti in un array in primo piano, ma cedendoli per l'elaborazione man mano che li si trova.

1

Se non è possibile utilizzare Fx4, è preferibile scrivere il proprio FileEnumerator. Ecco one example.

+0

+1. Stavo per suggerire qualcosa di simile come alternativa. Penso che CodeProject abbia anche qualcosa di simile. – RichardOD

1

Directory.GetFiles deve compilare un elenco di tutti i file corrispondenti prima che possa essere restituito. Solo allora puoi elencarli. Quindi, ovviamente, è costoso quando ci sono molti file corrispondenti. Può persino creare un elenco di tutti i file internamente.

Se è possibile utilizzare .NET 4.0, è possibile utilizzare Directory.EnumerateFiles per evitare questo problema eseguendo il backup di un file alla volta. Se non puoi, ti suggerirei di scrivere questo in C++ piuttosto che in C#.

In C++ è possibile utilizzare FindFirstFile che restituisce anche i file uno alla volta.

// iterate though the files in this directory 
// 
TCHAR szWild[MAX_PATH]; 
PathCombine(szWild, masterfolders, _T("*.txt")); 

WIN32_FIND_DATA fd; 
HANDLE hFind = FindFirstFile(szWild, &fd); 
if (INVALID_HANDLE_VALUE != hFind) 
{ 
    do { 
    TCHAR szFileName[MAX_PATH]; 
    PathCombine(szFileName, masterfolders, fd.cFileName); 

    // write szFilename to output stream.. 

    } while (FindNextFile(hFind, &fd)); 

    FindClose (hFind); 
} 
+0

che cosa sta usando? –

+0

Non sono sicuro di cosa TCHAR e WIN32_FInD-Data stiano utilizzando o siano riferimenti. –

+0

ahh n/m capito t/y –

Problemi correlati