Acceso al sistema de archivos con .NET (I)

 
Publicado el 09/May/2007
Actualizado el 09/May/2007
Autor: Guillermo 'guille' Som

Primera parte de los ejemplos de cómo acceder al sistema de archivos usando clases de .NET, por ejemplo para saber los ficheros que tiene una carpeta y otras funciones prácticas. Y como de costumbre, con código para VB como para C#.

 

 

Introducción:

Seguramente una de las acciones que harás habitualmente en tus aplicaciones es acceder al sistema de archivos, es decir, buscar un fichero en particular, saber si tal o cual fichero existe, crear carpetas y ficheros, etc. Esto se conoce como "acceso al sistema de archivos" y en este "artículo" te voy a explicar algunas cosas básicas para usarlas tanto con Visual Basic como con C#, pero siempre usando las clases de .NET Framework.

 

Nota:
En estos ejemplos voy a usar el Visual Studio 2005, pero posiblemente también será válido con Visual Studio 2003, aunque no lo he probado con esa versión, en cualquier caso, buscando en la ayuda puedes comprobar si las clases y métodos usados en estos ejemplos están disponibles y si no están... me lo dices y veré de crear un ejemplo que sea válido para las versiones anteriores al .NET Framework 2.0 que es la versión que usa actualmente el Visual Studio 2005, y cuando digo Visual Studio 2005 me refiero también a las versiones Express, tanto de Visual Basic 2005 como de Visual C# 2005.

 

No te voy a explicar toda la funcionalidad ni todas las clases y métodos, pero si que te explicaré cómo usar algunas de las más habituales y que serán las que seguramente utilices con más frecuencia.

Tampoco te voy a explicar cómo acceder a un fichero y leer el contenido, ya que eso lo puedes ver en estos dos artículos que ya publiqué:

 

Nota:
Para manipular directamente las clases de estos ejemplos debes tener una importación del espacio de nombres System.IO que es donde están definidas las clases para manejar todo el sistema de archivos.

 

Clases para manipular los directorios

Básicamente hay dos clases para manejar los directorios o carpetas de un disco duro (o cualquier disco).
La diferencia entre esas dos clase: Directory y DirectoryInfo es que la primera define métodos estáticos (compartidos) y por tanto puedes usarlos sin necesidad de crear una instancia de la clase. Por otro lado, la clase DirectoryInfo es una clase de instancia, es decir, debes crear un nuevo objeto para acceder a los métodos que define.

Debido a que la clase Directory no es de instancia y por tanto te permite acceder a cualquier directorio, en los métodos que define debes indicar el path o ruta a la que quieres acceder o con la que quieres trabajar, mientras que con DirectoryInfo debes crear una instancia indicando el directorio al que quieres acceder.

Nota:
En estos ejemplos voy a usar un proyecto de tipo consola para no "distraerte" con cosas que pueden complicar el código. En el caso del acceso a los directorio, el proyecto se llamará directorios_vb o directorios_cs según sea para Visual Basic o para Visual C#, en el ZIP con el código tienes el ejemplo completo, pero recuerda que están creados con Visual Studio 2005.

 

Saber si existe un directorio

Para saber si existe un directorio, usaremos el método Exists de la clase Directory o la propiedad Exists de la clase DirectoryInfo:

Visual Basic: 

'
' Saber si existe un directorio
'
Private Sub existeDir(ByVal elDirectorio As String)
    Dim existe As Boolean = Directory.Exists(elDirectorio)

    If existe Then
        Console.WriteLine("El directorio {0} SI existe", elDirectorio)
    Else
        Console.WriteLine("El directorio {0} NO existe", elDirectorio)
    End If
End Sub

Private Sub existeDirInfo(ByVal elDirectorio As String)
    Dim di As New DirectoryInfo(elDirectorio)
    Dim existe As Boolean = di.Exists

    If existe Then
        Console.WriteLine("El directorio {0} SI existe", elDirectorio)
    Else
        Console.WriteLine("El directorio {0} NO existe", elDirectorio)
    End If
End Sub

Visual C#: 

//
// Saber si existe un directorio
//
private static void existeDir(string elDirectorio)
{
    bool existe = Directory.Exists(elDirectorio);

    if (existe)
    {
        Console.WriteLine("El directorio {0} SI existe", elDirectorio);
    }
    else
    {
        Console.WriteLine("El directorio {0} NO existe", elDirectorio);
    }
}

private static void existeDirInfo(string elDirectorio)
{
    DirectoryInfo di = new DirectoryInfo(elDirectorio);
    bool existe = di.Exists;

    if (existe)
    {
        Console.WriteLine("El directorio {0} SI existe", elDirectorio);
    }
    else
    {
        Console.WriteLine("El directorio {0} NO existe", elDirectorio);
    }
}

 

Los subdirectorios de un directorio

Para saber los subdirectorios de un directorio (los directorios que un directorio en concreto contiene), usaremos el método GetDirectories. Aunque hay que tener en cuenta que si ese método se usa desde la clase Directory, lo que devuelve es un array de tipo String, mientras que si lo usamos desde una instancia de la clase DirectoryInfo, lo que devuelve es un array del tipo DirectoryInfo.

El método GetDirectories tiene varias sobrecargas, en una de ellas se pueden especificar un "pattern" o especificación para filtrar los directorios que el método devuelve.
Ver el cuadro "Caracteres comodines" para saber más sobre la especificación a usar.

Caracteres comodines:

En las especificaciones o patterns de algunos de los métodos, se pueden usar los caracteres comodines * y ?. El asterisco (*) indica cualquier carácter o caracteres, mientras que la interrogación (?) se puede usar para indicar "cualquier carácter en esa posición".

Por ejemplo:
datos* buscará todo lo que empiece con la palabra datos: datos07 o datosAbril, pero no misdatos.
datos??07 buscará todo lo que empiece con la palabra datos, tenga dos caracteres cualesquiera en las posiciones 6 y 7 y termine con 07: datos0107, pero no datos01abr07.

En las especificaciones no se distinguen las mayúsculas de las minúsculas, por tanto DatOS será lo mismo que DATOS o datos.

 

Visual Basic: 

'
' Los subdirectorios de un directorio
'
Private Sub subDir(ByVal elDirectorio As String)
    Dim subdirs() As String = Directory.GetDirectories(elDirectorio)

    Console.WriteLine("Los subdirectorios del directorio {0}", elDirectorio)
    For Each s As String In subdirs
        Console.WriteLine("  {0}", s)
    Next
End Sub

Private Sub subDirInfo(ByVal elDirectorio As String)
    Dim di As New DirectoryInfo(elDirectorio)
    Dim subdirs() As DirectoryInfo = di.GetDirectories

    Console.WriteLine("Los subdirectorios del directorio {0}", elDirectorio)
    For Each d As DirectoryInfo In subdirs
        Console.WriteLine("  {0}", d.FullName)
    Next
End Sub

Visual C#: 

//
// Los subdirectorios de un directorio
//
private static void subDir(string elDirectorio)
{
    string[] subdirs = Directory.GetDirectories(elDirectorio);

    Console.WriteLine("Los subdirectorios del directorio {0}", elDirectorio);
    foreach (string s in subdirs)
    {
        Console.WriteLine("  {0}", s);
    }
}

private static void subDirInfo(string elDirectorio)
{
    DirectoryInfo di = new DirectoryInfo(elDirectorio);
    DirectoryInfo[] subdirs = di.GetDirectories();

    Console.WriteLine("Los subdirectorios del directorio {0}", elDirectorio);
    foreach (DirectoryInfo d in subdirs)
    {
        Console.WriteLine("  {0}", d.FullName);
    }
}

 

Los ficheros de un directorio

Para averiguar los ficheros que contiene un directorio, usaremos el método GetFiles. Aunque hay que tener en cuenta que si ese método se usa desde la clase Directory, lo que devuelve es un array de tipo String, mientras que si lo usamos desde una instancia de la clase DirectoryInfo, lo que devuelve es un array del tipo FileInfo.

El método GetFiles tiene varias sobrecargas, en una de ellas se pueden especificar un "pattern" o especificación para filtrar los ficheros que el método devuelve.
Ver el cuadro "Caracteres comodines" para saber más sobre la especificación a usar.

Esa especificación solo puede contener un tipo, por ejemplo, si quieres recuperar todos los ficheros con la extensión .txt puedes usar *.txt, pero si quieres todos los ficheros que tengan la extensión .txt y todos los que tengan la extensión .doc no puedes usar *.txt; *.doc, sino que tendrás que hacerlo para un tipo cada vez.

En el siguiente ejemplo se muestran todos los ficheros con la extensión .txt.

 

Visual Basic: 

' 
' Los ficheros de un directorio
'
Private Sub filesDir(ByVal elDirectorio As String)
    Dim ficheros() As String = Directory.GetFiles(elDirectorio, "*.txt")

    Console.WriteLine("Los ficheros del directorio {0}", elDirectorio)
    For Each s As String In ficheros
        Console.WriteLine("  {0}", s)
    Next
End Sub

Private Sub filesDirInfo(ByVal elDirectorio As String)
    Dim di As New DirectoryInfo(elDirectorio)
    Dim ficheros() As FileInfo = di.GetFiles("*.txt")

    Console.WriteLine("Los subdirectorios del directorio {0}", elDirectorio)
    For Each f As FileInfo In ficheros
        Console.WriteLine("  {0}", f.FullName)
    Next
End Sub

Visual C#:

//
// Los ficheros de un directorio
//
private static void filesDir(string elDirectorio)
{
    string[] ficheros = Directory.GetFiles(elDirectorio, "*.txt");

    Console.WriteLine("Los ficheros del directorio {0}", elDirectorio);
    foreach (string s in ficheros)
    {
        Console.WriteLine("  {0}", s);
    }
}

private static void filesDirInfo(string elDirectorio)
{
    DirectoryInfo di = new DirectoryInfo(elDirectorio);
    FileInfo[] ficheros = di.GetFiles("*.txt");

    Console.WriteLine("Los subdirectorios del directorio {0}", elDirectorio);
    foreach (FileInfo f in ficheros)
    {
        Console.WriteLine("  {0}", f.FullName);
    }
}

 

Recorrer de forma recursiva un directorio

Algo que seguramente necesitarás es recorrer de forma recursiva un directorio, es decir, si quieres saber qué subdirectorios tiene un directorio en concreto, por ejemplo E:\Pruebas, puede que también te interese saber qué subdirectorios contiene, por ejemplo E:\Pruebas\textos y a su vez que subdirectorios tiene ese directorio y así hasta que ya no haya más subdirectorios. Lo mismo es aplicable a los ficheros que contiene cada directorio.

En el siguiente ejemplo te muestro una de las formas de hacer esa "recursividad" usando la clase Directory y como "ejercicio" puedes hacer lo mismo con la clase DirectoryInfo, en el ZIP con el código tienes una posible solución.

Visual Basic:

'
' Recorrer recursivamente los directorios
' Para mostrar los ficheros de un directorio
' y los de los subdirectorios que ese directorio contenga.
'
Private Sub recursivoDir(ByVal elDirectorio As String)
    Console.WriteLine("Los subdirectorios de {0}", elDirectorio)
    recorrerDir(elDirectorio, 0)
End Sub

Private Sub recorrerDir(ByVal elDir As String, ByVal nivel As Integer)
    ' La sangría del nivel examinado
    Dim sangria As String = New String(" "c, nivel)

    ' Los subdirectorios del directorio indicado
    Dim directorios As String() = Directory.GetDirectories(elDir)
    Console.Write("{0}Directorio {1} con {2} subdirectorios", _
                    sangria, elDir, directorios.Length)
    Dim ficheros As String() = Directory.GetFiles(elDir)
    Console.WriteLine(" y {0} ficheros", ficheros.Length)

    ' Si tiene subdirectorios, recorrerlos
    If directorios.Length > 0 Then
        For Each d As String In directorios
            ' Llamar de forma recursiva a este mismo método
            recorrerDir(d, nivel + 2)
        Next
    End If
End Sub

Visual C#: 

//
// Recorrer recursivamente los directorios
// Para mostrar los ficheros de un directorio
// y los de los subdirectorios que ese directorio contenga.
//
private static void recursivoDir(string elDirectorio)
{
    Console.WriteLine("Los sus subdirectorios de {0}", elDirectorio);
    recorrerDir(elDirectorio, 0);
}

private static void recorrerDir(string elDir, int nivel)
{
    // La sangría del nivel examinado
    string sangria = new string(' ', nivel);

    // Los subdirectorios del directorio indicado
    string[] directorios = Directory.GetDirectories(elDir);
    Console.Write("{0}Directorio {1} con {2} subdirectorios", 
                        sangria, elDir, directorios.Length);
    string[] ficheros = Directory.GetFiles(elDir);
    Console.WriteLine(" y {0} ficheros", ficheros.Length);

    // Si tiene subdirectorios, recorrerlos
    if (directorios.Length > 0)
    {
        foreach (string d in directorios)
        {
            // Llamar de forma recursiva a este mismo método
            recorrerDir(d, nivel + 2);
        }
    }
}

 

Bueno, esto es todo por hoy, y como siempre: Espero que te sea de utilidad.

Nos vemos.
Guillermo

 


Espacios de nombres usados en el código de este artículo:

System.IO
 


Código de ejemplo (comprimido):

Fichero con el código de ejemplo: Sistema_archivos.zip - 12.60 KB

Contiene los proyectos para Visual Basic 2005 y Visual C# 2005.

(MD5 checksum: FF6219616D9D6ABA6EB59166094766FD)


Ir al índice principal de el Guille

Valid XHTML 1.0 Transitional ¡CSS Válido!