Renombrar archivos II

Mayo 11, 2008

Bueno, le añadí un grado de complejidad mayor al problema que tuve (Renombrar Archivo I), y fue la búsqueda de archivos que coincidan con un patrón de expresiones regulares que yo indique (por ejemplo, aquellos archivos que comiencen con cinco números, que tengan un arroba o guión en la posición 2, etc) y por ello cree estos métodos para añadirlos a mi módulo. Además, si por A o B encontrara muchos archivos en las carpetas, pensé que sería más rápido el cambio de nombres si lo hacían en hilos que trabajen en paralelo (en una PC que pueda provechar ello). A ver si lo prueban en distintos escenarios y me comentan cómo les fue.

    ”’ <summary>

    ”’ Cambia los nombres de los archivos que coincidan con el patrón de expresiones regulares especificado

    ”’ </summary>

    ”’ <param name=”rutaCarpeta”>Ubicación donde encontramos a los archivos</param>

    ”’ <param name=”criterioBusquedaArchivoRegex”>Patrón RegEx de búsqueda que deben cumplir los nombres de los archivos para ser considerados. Seguir el estándar de Windows</param>

    ”’ <param name=”cadenaReemplazable”>La cadena que será reemplazada</param>

    ”’ <param name=”cadenaReemplazante”>La nueva cadena que reemplazará a la anterior</param>

    ”’ <param name=”buscarEnCarpetasInternas”>Indica si se busca en subcarpetas. Por defecto, sí</param>

    ”’ <returns>Un listado con los archivos encontrados y sus resultados (positivo o negativo)</returns>

    ”’ <remarks>Lanzará una excepción del tipo DirectoryNotFoundException si no existe el directorio especificado</remarks>

    Public Function CambiarNombresRegEx(ByVal rutaCarpeta As String, _

            ByVal criterioBusquedaArchivoRegex As String, _

            ByVal cadenaReemplazable As String, _

            ByVal cadenaReemplazante As String, _

            Optional ByVal buscarEnCarpetasInternas As Boolean = True, _

            Optional ByVal tamañoArreglosParalelos As Integer = 100) As IDictionary(Of String, Boolean)

        ‘Aqui almacenamos temporalmente los nombres de los archivos

        Dim astrNombreArchivos(), astrNombreArchivosCopiados(tamañoArreglosParalelos) As String

        Dim aobjParametrosMetodoPorEjecutar As IList

        ‘Aqui almacenamos los resultados de renombrar cada archivo

        ‘(No debería haber dos archivos con el mismo nombre)

        Dim aobjArchivosCambiados As Generic.Dictionary(Of String, Boolean)

        Dim objHiloEjecucionCambio As Thread

        Dim metodoPorEjecutar As Threading.ParameterizedThreadStart

 

        ‘Si existe la ruta podemos proseguir

        If Directory.Exists(rutaCarpeta) Then

 

            ‘Le asignamos todos los archivos

            astrNombreArchivos = Directory.GetFiles(rutaCarpeta, _

                    “*.*”, _

                    IIf(buscarEnCarpetasInternas, SearchOption.AllDirectories, SearchOption.TopDirectoryOnly))

 

            ‘Inicializamos el listado de resultados por cada archivo

            aobjArchivosCambiados = New Dictionary(Of String, Boolean)

 

            ‘Si es necesario usar arreglos paralelos…

            If astrNombreArchivos.LongLength > tamañoArreglosParalelos Then

                ‘Especificamos los parametros del método

                aobjParametrosMetodoPorEjecutar = New ArrayList

                With aobjParametrosMetodoPorEjecutar

                    .Add(rutaCarpeta) : .Add(Nothing) : .Add(aobjArchivosCambiados)

                    .Add(criterioBusquedaArchivoRegex) : .Add(cadenaReemplazable) : .Add(cadenaReemplazante)

                End With

                ‘Indicamos cual es el metodo a ejecutar en cada hilo

                metodoPorEjecutar = New Threading.ParameterizedThreadStart(AddressOf CambiarNombreRegEx)

 

                ‘Creamos y ejecutamos los hilos

                For i As Long = 0 To astrNombreArchivos.LongLength Step tamañoArreglosParalelos

                    Array.Copy(astrNombreArchivos, i, astrNombreArchivosCopiados, 0, tamañoArreglosParalelos)

                    aobjParametrosMetodoPorEjecutar(1) = astrNombreArchivosCopiados

                    objHiloEjecucionCambio = New Thread(metodoPorEjecutar)

                    objHiloEjecucionCambio.Start(aobjParametrosMetodoPorEjecutar)

                    objHiloEjecucionCambio = Nothing

                Next

            Else

                ‘Ejecutamos el cambio de nombre, simplemente

                CambiarNombreRegEx(rutaCarpeta, _

                        astrNombreArchivos, _

                        aobjArchivosCambiados, _

                        criterioBusquedaArchivoRegex, _

                        cadenaReemplazable, _

                        cadenaReemplazante)

            End If

        Else

            Throw New DirectoryNotFoundException( _

                    String.Format(“No se encontró la carpeta {0}, por lo que no se pudo realizar el renombrado de archivos.”, _

                    rutaCarpeta))

        End If

        ‘Recogemos toda el desperdicio de objetos luego de la iteración

        GC.Collect()

        ‘Retornamos los resultados de los archivos

        Return aobjArchivosCambiados

    End Function

 

    Private Sub CambiarNombreRegEx(ByVal obj As Object)

        Dim aobjParametros As IList

        aobjParametros = CType(obj, IList)

        CambiarNombreRegEx(aobjParametros(0), _

                aobjParametros(1), _

                aobjParametros(2), _

                aobjParametros(3), _

                aobjParametros(4), _

                aobjParametros(5))

    End Sub

 

    Private Sub CambiarNombreRegEx(ByVal rutaCarpeta As String, _

            ByVal listadoArchivos As String(), _

            ByRef listadoArchivosCambiados As IDictionary(Of String, Boolean), _

            ByVal criterioBusquedaArchivoRegex As String, _

            ByVal cadenaReemplazable As String, _

            ByVal cadenaReemplazante As String)

        Dim strArchivoRenombrado As String

        ‘Por cada archivo encontrado

        For Each strNombreArchivo As String In listadoArchivos

            ‘Si coincide con el patron RegEx…

            If Regex.IsMatch(strNombreArchivo, criterioBusquedaArchivoRegex) Then

                ‘Añadimos el resultado como positivo (si no es así lo cambiamos en el error)

                listadoArchivosCambiados.Add(strNombreArchivo, True)

                strArchivoRenombrado = _

                        rutaCarpeta & _

                        strNombreArchivo.Substring(strNombreArchivo.LastIndexOf(“\”)).Replace(cadenaReemplazable, cadenaReemplazante)

                Try

                    ‘Movemos el archivo con los cambios especificados

                    File.Move(strNombreArchivo, strArchivoRenombrado)

                Catch ex As Exception

                    ‘Cambiamos el resultado a negativo

                    listadoArchivosCambiados(strNombreArchivo) = False

                End Try

            End If

        Next

    End Sub

Escribe un comentario