Condividi tramite


Procedura: enumerare directory e file

A partire da .NET Framework versione 4, è possibile enumerare directory e file tramite metodi che restituiscono un insieme enumerabile di stringhe dei relativi nomi. È inoltre possibile utilizzare metodi che restituiscono un insieme enumerabile di oggetti DirectoryInfo, FileInfo o FileSystemInfo. Nelle versioni precedenti di .NET Framework, era possibile ottenere solo le matrici di questi insiemi. Gli insiemi enumerabili offrono prestazioni migliori rispetto alle matrici.

È anche possibile utilizzare gli insiemi enumerabili ottenuti da questi metodi per fornire il parametro IEnumerable<T> per i costruttori di classi di insiemi quale la classe List<T>.

Per ottenere solo i nomi delle directory o dei file, utilizzare i metodi di enumerazione della classe Directory. Per ottenere altre proprietà delle directory o dei file, utilizzare le classi DirectoryInfo e FileSystemInfo. È anche possibile enumerare le righe di un file di testo.

Nella tabella seguente viene fornita una guida ai metodi che restituiscono insiemi enumerabili.

Da enumerare

Insieme enumerabile da restituire

Metodo da utilizzare

Directory

Nomi di directory.

Directory.EnumerateDirectories

Informazioni sulle directory (DirectoryInfo).

DirectoryInfo.EnumerateDirectories

File

Nomi di file.

Directory.EnumerateFiles

Informazioni sui file (FileInfo).

DirectoryInfo.EnumerateFiles

Informazioni sul file system

Voci di file system.

Directory.EnumerateFileSystemEntries

Informazioni sul file system (FileSystemInfo).

DirectoryInfo.EnumerateFileSystemInfos

Righe di un file di testo

Righe di un file.

File.ReadLines

Sebbene sia possibile enumerare immediatamente tutti i file nelle sottodirectory di una directory padre tramite l'opzione AllDirectories, le eccezioni di accesso non autorizzato (UnauthorizedAccessException) possono causare un'enumerazione incompleta. Qualora esista la possibilità di tali eccezioni, è possibile rilevarle e proseguire enumerando prima le directory, quindi i file.

Se si esegue Windows XP o una versione precedente, un'operazione di eliminazione in un file o in una directory che segue un'enumerazione potrebbe non riuscire se esiste un handle aperto che rimane in una delle directory o dei file enumerati. Se si verifica questa condizione, è necessario forzare un'operazione di Garbage Collection per rimuovere gli handle aperti.

Per enumerare nomi di directory

  • Utilizzare il metodo Directory.EnumerateDirectories(String) per ottenere un elenco dei nomi delle directory di primo livello in un percorso specificato.

    Imports System.Collections.Generic
    Imports System.IO
    Imports System.Linq
    
    Module Module1
    
        Sub Main()
            Try
                Dim dirPath As String = "\\archives\2009\reports"
    
                ' LINQ query.
                Dim dirs = From folder In _
                    Directory.EnumerateDirectories(dirPath)
                For Each folder In dirs
                    ' Remove path information from string.
                    Console.WriteLine("{0}", _
                            folder.Substring(folder.LastIndexOf("\") + 1))
                Next
                Console.WriteLine("{0} directories found.", _
                    dirs.Count.ToString())
    
                ' Optionally create a List collection.
                Dim workDirs As List(Of String) = New List(Of String)(dirs)
    
            Catch UAEx As UnauthorizedAccessException
                Console.WriteLine(UAEx.Message)
            Catch PathEx As PathTooLongException
                Console.WriteLine(PathEx.Message)
            End Try
        End Sub
    End Module
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    
    class Program
    {
    
        private static void Main(string[] args)
        {
            try
            {
                string dirPath = @"\\archives\2009\reports";
    
                // LINQ query.
                var dirs = from dir in 
                         Directory.EnumerateDirectories(dirPath)
                           select dir;
    
                // Show results.
                foreach (var dir in dirs)
                {
                    // Remove path information from string.
                    Console.WriteLine("{0}", 
                        dir.Substring(dir.LastIndexOf("\\") + 1));
    
                }
                Console.WriteLine("{0} directories found.", 
                    dirs.Count<string>().ToString());
    
                // Optionally create a List collection.
                List<string> workDirs = new List<string>(dirs);
            }
            catch (UnauthorizedAccessException UAEx)
            {
                Console.WriteLine(UAEx.Message);
            }
            catch (PathTooLongException PathEx)
            {
                Console.WriteLine(PathEx.Message);
            }
        }
    }
    

Per enumerare i nomi di file in tutte le directory

  • Utilizzare il metodo Directory.EnumerateFiles(String, String, SearchOption) per eseguire una ricerca in tutte le directory e ottenere un elenco dei nomi dei file in un percorso specificato corrispondenti a un criterio di ricerca specificato.

    Imports System.IO
    Imports System.Xml.Linq
    Module Module1
    
        Sub Main()
    
            Try
                Dim files = From chkFile In Directory.EnumerateFiles("c:\", "*.txt", _
                                                     SearchOption.AllDirectories)
                            From line In File.ReadLines(chkFile)
                            Where line.Contains("Microsoft")
                            Select New With {.curFile = chkFile, .curLine = line}
    
                For Each f In files
                    Console.WriteLine("{0}\t{1}", f.curFile, f.curLine)
                Next
                Console.WriteLine("{0} files found.", _
                        files.Count.ToString())
            Catch UAEx As UnauthorizedAccessException
                Console.WriteLine(UAEx.Message)
            Catch PathEx As PathTooLongException
                Console.WriteLine(PathEx.Message)
            End Try
        End Sub
    End Module
    
    using System;
    using System.IO;
    using System.Linq;
    
    class Program
    {
        static void Main(string[] args)
        {
    
            try
            {
                var files = from file in Directory.EnumerateFiles(@"c:\",
                                "*.txt", SearchOption.AllDirectories)
                            from line in File.ReadLines(file)
                            where line.Contains("Microsoft")
                            select new
                            {
                                File = file,
                                Line = line
                            };
    
                foreach (var f in files)
                {
                    Console.WriteLine("{0}\t{1}", f.File, f.Line);
                }
                Console.WriteLine("{0} files found.", 
                    files.Count().ToString());
            }
            catch (UnauthorizedAccessException UAEx)
            {
                Console.WriteLine(UAEx.Message);
            }
            catch (PathTooLongException PathEx)
            {
                Console.WriteLine(PathEx.Message);
            }
        }
    }
    

Per enumerare un insieme di oggetti DirectoryInfo

  • Utilizzare il metodo DirectoryInfo.EnumerateDirectories per ottenere un insieme di directory di primo livello.

    ' Create a DirectoryInfo of the Program Files directory.
    Dim dirPrograms As New DirectoryInfo("c:\program files")
    
    Dim StartOf2009 As New DateTime(2009, 1, 1)
    
    ' LINQ query for all directories created before 2009.
    Dim dirs = From dir In dirPrograms.EnumerateDirectories()
                Where dir.CreationTimeUtc < StartOf2009
    
    ' Show results.
    For Each di As DirectoryInfo In dirs
        Console.WriteLine("{0}", di.Name)
    Next
    
    // Create a DirectoryInfo of the Program Files directory.
    DirectoryInfo dirPrograms = new DirectoryInfo(@"c:\program files");
    
    DateTime StartOf2009 = new DateTime(2009, 01, 01);
    
    // LINQ query for all directories created before 2009.
    var dirs = from dir in dirPrograms.EnumerateDirectories()
                where dir.CreationTimeUtc < StartOf2009
                select new
                {
                    ProgDir = dir,
                };
    // Show results.
    foreach (var di in dirs)
    {
        Console.WriteLine("{0}", di.ProgDir.Name);
    }
    

Per enumerare un insieme di oggetti FileInfo in tutte le directory

  • Utilizzare il metodo DirectoryInfo.EnumerateFiles per ottenere un insieme di file corrispondenti a un criterio di ricerca specificato in tutte le directory. In questo esempio vengono prima enumerate le directory di primo livello per rilevare possibili eccezioni di accesso non autorizzato, quindi vengono enumerati i file.

    Imports System
    Imports System.IO
    
    Class Program
        Public Shared Sub Main(ByVal args As String())
            ' Create a DirectoryInfo object of the starting directory.
            Dim diTop As New DirectoryInfo("d:\")
            Try
                ' Enumerate the files just in the top directory.
                For Each fi In diTop.EnumerateFiles()
                    Try
                        ' Display each file over 10 MB;
                        If fi.Length > 10000000 Then
                            Console.WriteLine("{0}" & vbTab & vbTab & "{1}", 
                            fi.FullName, fi.Length.ToString("N0"))
                        End If
                    ' Catch unauthorized access to a file.
                    Catch UnAuthTop As UnauthorizedAccessException
                        Console.WriteLine("{0}", UnAuthTop.Message)
                    End Try
                Next
                ' Enumerate all subdirectories.
                For Each di In diTop.EnumerateDirectories("*")
                    Try
                        ' Enumerate each file in each subdirectory.
                        For Each fi In di.EnumerateFiles("*", 
                                    SearchOption.AllDirectories)
                            Try
                                ' // Display each file over 10 MB;
                                If fi.Length > 10000000 Then
                                    Console.WriteLine("{0}" & vbTab &
                                    vbTab & "{1}", 
                                    fi.FullName, fi.Length.ToString("N0"))
                                End If
                            ' Catch unauthorized access to a file.
                            Catch UnAuthFile As UnauthorizedAccessException
                                Console.WriteLine("UnAuthFile: {0}",
                                                    UnAuthFile.Message)
                            End Try
                        Next
                    ' Catch unauthorized access to a subdirectory.
                    Catch UnAuthSubDir As UnauthorizedAccessException
                        Console.WriteLine("UnAuthSubDir: {0}", 
                                                UnAuthSubDir.Message)
                    End Try
                Next
            ' Catch error in directory path.
            Catch DirNotFound As DirectoryNotFoundException
                Console.WriteLine("{0}", DirNotFound.Message)
            ' Catch unauthorized access to a first tier directory. 
            Catch UnAuthDir As UnauthorizedAccessException
                Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message)
            ' Catch paths that are too long.
            Catch LongPath As PathTooLongException
                Console.WriteLine("{0}", LongPath.Message)
            End Try
        End Sub
    End Class
    
    using System;
    using System.IO;
    
    class Program
    {
        static void Main(string[] args)
        {
            // Create a DirectoryInfo object of the starting directory.
            DirectoryInfo diTop = new DirectoryInfo(@"d:\");
            try
            {
                // Enumerate the files just in the top directory.
                foreach (var fi in diTop.EnumerateFiles())
                {
                    try
                    {
                        // Display each file over 10 MB;
                        if (fi.Length > 10000000)
                        {
                            Console.WriteLine("{0}\t\t{1}", fi.FullName, 
                                            fi.Length.ToString("N0"));
                        }
                    }
                    // Catch unauthorized access to a file.
                    catch (UnauthorizedAccessException UnAuthTop)
                    {
                        Console.WriteLine("{0}", UnAuthTop.Message);
                    }
                }
                // Enumerate all subdirectories.
                foreach (var di in diTop.EnumerateDirectories("*"))
                {
                    try
                    {
                        // Enumerate each file in each subdirectory.
                        foreach (var fi in di.EnumerateFiles("*",
                                        SearchOption.AllDirectories))
                        {
                            try
                            {
                                // Display each file over 10 MB;
                                if (fi.Length > 10000000)
                                {
                                    Console.WriteLine("{0}\t\t{1}", 
                                      fi.FullName, fi.Length.ToString("N0"));
                                }
                            }
                             // Catch unauthorized access to a file.
                            catch (UnauthorizedAccessException UnAuthFile)
                            {
                                Console.WriteLine("UnAuthFile: {0}", 
                                                UnAuthFile.Message);
                            }
                        }
                    }
                    // Catch unauthorized access to a subdirectory.
                    catch (UnauthorizedAccessException UnAuthSubDir)
                    {
                        Console.WriteLine("UnAuthSubDir: {0}", 
                                                UnAuthSubDir.Message);
                    }
                }
            }
            // Catch error in directory path.
            catch (DirectoryNotFoundException DirNotFound)
            {
                Console.WriteLine("{0}", DirNotFound.Message);
            }
            // Catch unauthorized access to a first tier directory. 
            catch (UnauthorizedAccessException UnAuthDir)
            {
                Console.WriteLine("UnAuthDir: {0}", UnAuthDir.Message);
            }
            // Catch paths that are too long. 
            catch (PathTooLongException LongPath)
            {
                Console.WriteLine("{0}", LongPath.Message);
            }
    
        }
    }
    

Per rimuovere gli handle aperti in directory o file enumerati

  1. Creare un metodo personalizzato, o una funzione in Visual Basic, per contenere il codice di enumerazione.

  2. Applicare l'attributo MethodImplAttribute con l'opzione NoInlining al nuovo metodo. Esempio:

    [MethodImplAttribute(MethodImplOptions.NoInlining)]
    Private void Enumerate()
    
  3. Includere le chiamate al metodo seguenti, da eseguire dopo il codice di enumerazione:

Vedere anche

Concetti

I/O di file di base