[SOLUCIONADO] Una pregunta sobre IO.Directory.GetFiles

Iniciado por Eleкtro, 18 Enero 2013, 10:10 AM

0 Miembros y 3 Visitantes están viendo este tema.

Eleкtro

¿No se puede usar algún separador de expresión?

He intentado esto:

Código (vbnet) [Seleccionar]

IO.Directory.GetFiles(Directory, "*.exe, *.vb")

IO.Directory.GetFiles(Directory, "*.exe; *.vb")

IO.Directory.GetFiles(Directory, "*.exe" + "*.vb")

IO.Directory.GetFiles(Directory, "*.exe" + IO.Path.AltDirectorySeparatorChar + "*.vb")

IO.Directory.GetFiles(Directory, "*.exe" + IO.Path.DirectorySeparatorChar + "*.vb")








Novlucker

Hasta donde se no :-\ Puedes obtener todos los resultados y filtrar, o bien puedes buscar varias veces, pero no directamente :-\

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein


Eleкtro

#3
Puf, para perder tiempo de lectura de disco haciendo múltiples búsquedas y/o filtrando la lista... busco algo más "natural"
creo que jamás diría esto, pero es que para eso es mejor usar el comando "DIR" de la CMD (en VB.NET) sincéramente xD.

@3mp3z@ndo
Gracias por la info , parece la mejor opción pero me queda la duda,

¿Esto solo hace una búsqueda y filtra, o hace dos búsquedas?
Código (VBNET) [Seleccionar]
Dim files = Directory.GetFiles("C:\", "*").Where(Function(s) s.EndsWith(".exe") OrElse s.EndsWith(".xml"))








Novlucker

Cita de: EleKtro H@cker en 18 Enero 2013, 13:17 PM
¿Esto solo hace una búsqueda y filtra, o hace dos búsquedas?
Código (VBNET) [Seleccionar]
Dim files = Directory.GetFiles("C:\", "*").Where(Function(s) s.EndsWith(".exe") OrElse s.EndsWith(".xml"))
Primero listas todos los archivos (*.*) y luego filtras en memoria

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Eleкtro

#5
Como se podría optimizar el código para crear una función de esto?

Por ejemplo:

Código (vbnet) [Seleccionar]
   Private Sub Form1_Load()
       Dim File_Extensions() As String = {"*.txt", "*.ini", "*.exe", "*.pdf"}
       Dim Files() = Get_Files_By_FileExtensions("C:\", File_Extensions)
   End Sub


Y entonces aquí se debería agregar automáticamente un "orelse s.EndsWith(siguiente extensión)" por cada extensión de la colección:
Código (vbnet) [Seleccionar]
   Public Function Get_Files_By_FileExtensions(ByVal Directory As String, ByVal Extensions() As String) As System.IO.FileInfo()
       Return IO.Directory.GetFiles(Directory, "*").Where(Function(s) s.EndsWith(Extensions(0)) _
       OrElse s.EndsWith(Extensions(1)) _
       OrElse s.EndsWith(Extensions(2)) _
       OrElse s.EndsWith(Extensions(3)))
   End Function


¿Es posible hacerlo?


EDITO: Yo ya tengo funciones para listar archivos, pero preciso hacerlo con ese código que menciono (me resulta más limpio porque sólo hace una búsqueda)








_katze_

si quieres algo rapido y optimo, usas apis, regular expresion,

Eleкtro

Cita de: _katze_ en 26 Enero 2013, 18:18 PM
si quieres algo rapido y optimo, usas apis, regular expresion,

Gracias, pero podrías indicarme (para buscar info) con que API y que función _katze_?








_katze_

codigo vieejo y con ayuda de varias, pero la connserve y justo t viene para aprender

Código (vbnet) [Seleccionar]
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Imports System.Text
Imports System.IO

Public Class ClsBucarFiles

#Region "   Icon    "

    Private Structure SHFILEINFO
        Public hIcon As IntPtr ' : icon
        Public iIcon As Integer ' : icondex
        Public dwAttributes As Integer ' : SFGAO_ flags
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
        Public szDisplayName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
        Public szTypeName As String
    End Structure

    Private Declare Ansi Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, _
    ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, _
    ByVal uFlags As Integer) As IntPtr

    Private Const SHGFI_SMALLICON As Long = &H1
    Private Const SHGFI_SYSICONINDEX As Long = &H4000
    Private Const SHGFI_USEFILEATTRIBUTES As Long = &H10
    Private Const SHGFI_TYPENAME As Long = &H400
    Private Const SHGFI_DISPLAYNAME As Long = &H200
    Private Const SHGFI_ICON = &H100
    Private Const SHGFI_LARGEICON = &H0         ' Large icon
    Private Shared shfitmp As SHFILEINFO   'just used for the following
    Private Shared SHFILESIZE As Integer = Marshal.SizeOf(shfitmp.GetType())

    Public Function ptricon(ByVal vsPath As String) As IntPtr
        Dim hImgSmall As IntPtr
        Dim shinfo As New SHFILEINFO()
        shinfo.szDisplayName = New String(Chr(0), 260)
        shinfo.szTypeName = New String(Chr(0), 80)
        hImgSmall = SHGetFileInfo(vsPath, 0&, shinfo, SHFILESIZE, _
        SHGFI_ICON Or SHGFI_SYSICONINDEX Or SHGFI_SMALLICON)
        Return (shinfo.hIcon)
    End Function

#End Region

#Region " Declaraciones "
    <DllImport("kernel32.dll")> _
    Private Shared Function FindClose(ByVal hFindFile As IntPtr) As Boolean
    End Function

    <DllImport("kernel32.dll", CharSet:=CharSet.None)> _
    Private Shared Function FindFirstFile(ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As IntPtr
    End Function

    Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As IntPtr, ByRef lpFindFileData As WIN32_FIND_DATA) As Boolean

    <StructLayout(LayoutKind.Sequential)> _
    Structure WIN32_FIND_DATA
        Public dwFileAttributes As UInteger
        Public ftCreationTime As System.Runtime.InteropServices.ComTypes.FILETIME
        Public ftLastAccessTime As System.Runtime.InteropServices.ComTypes.FILETIME
        Public ftLastWriteTime As System.Runtime.InteropServices.ComTypes.FILETIME
        Public nFileSizeHigh As UInteger
        Public nFileSizeLow As UInteger
        Public dwReserved0 As UInteger
        Public dwReserved1 As UInteger
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> Public cFileName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> Public cAlternateFileName As String
    End Structure


    Public Event FileFound(ByVal sPath As String, ByVal sFile As String, ByVal atributos As FileAttributes)
    Public Event FolderFound(ByVal sPath As String, ByVal sFolder As String, ByVal atributos As FileAttributes)

    Private cancel As Boolean = False

    Private INVALID_HANDLE_VALUE As New IntPtr(-1)

    Private RegExp As Regex

    Private sbFiles As New StringBuilder

    Private sbFolders As New StringBuilder
#End Region

#Region " PRocedimientos "

    Public Sub New()

        MyBase.New()
    End Sub

    Public Sub start()
        If RegExp Is Nothing Then
            RegExp = New Regex(p_match, RegexOptions.IgnoreCase)
        Else
            RegExp = Nothing
            RegExp = New Regex(p_match, RegexOptions.IgnoreCase)
        End If

        cancel = False

        Dim arrdrive() As String

        arrdrive = p_path.Split(Chr(59))

        For Each s As String In arrdrive
            Call SubBusqueda(s) 'recursividad xD
        Next
       
    End Sub

    Public Sub Cancelar()
        cancel = True
    End Sub
    Private Function StripNulls(ByVal sData As String) As String
        StripNulls = Left$(sData, Len(sData))
    End Function
    Private Sub SubBusqueda(ByVal vsPath As String)
        Dim ptrSearch As New IntPtr
        Dim vsfile As String = String.Empty
        Dim vsfolder As String = String.Empty
        Dim vaDir As New ArrayList
        Dim wfd As New WIN32_FIND_DATA
        Dim dir As String = String.Empty
        Dim ret As Boolean

        If cancel Then Exit Sub

        Call NormalizePath(vsPath)
        ptrSearch = FindFirstFile(vsPath & "*", wfd)

        If Not ptrSearch = INVALID_HANDLE_VALUE Then

            Do
                If (wfd.dwFileAttributes And FileAttributes.Directory) <> FileAttributes.Directory Then
                    vsfile = StripNulls(wfd.cFileName)

                    If Not p_hide Then

                        If (wfd.dwFileAttributes And FileAttributes.Hidden) = FileAttributes.Hidden Then GoTo FNEXT

                    End If

                    If RegExp.Matches(vsfile).Count = 0 Then GoTo FNEXT

                    sbFiles.AppendLine(vsfile)

                    RaiseEvent FileFound(vsPath, vsfile, CType(wfd.dwFileAttributes, FileAttributes))
                Else

                    If Not p_hide Then
                        If (wfd.dwFileAttributes And FileAttributes.Hidden) = FileAttributes.Hidden Then GoTo FNEXT
                    End If

                    vsfolder = StripNulls(wfd.cFileName)

                    If (vsfolder <> ".") And (vsfolder <> "..") Then
                        dir = vsPath & vsfolder & "\"

                        If Not p_sys Then
                         
                            If dir = Environ("Windir") & "\" Then GoTo FNEXT
                        End If

                        vaDir.Add(dir)
                        If RegExp.Matches(vsfolder).Count = 0 Then GoTo FNEXT
                        sbFolders.AppendLine(vsfolder)
                        RaiseEvent FolderFound(vsPath, vsfolder, CType(wfd.dwFileAttributes, FileAttributes))

                    End If
                End If
FNEXT:

                If cancel Then FindClose(ptrSearch) : Exit Sub
                Application.DoEvents()

                ret = FindNextFile(ptrSearch, wfd)
            Loop While ret
            Call FindClose(ptrSearch)
        End If

        If p_subfolder Then

            For i As Integer = 0 To vaDir.Count - 1

                Call SubBusqueda(CStr(vaDir(i)))
            Next

        End If
    End Sub

    Private Function drivers() As String
        Dim drive As DriveInfo
        Dim dr As New StringBuilder

        For Each drive In DriveInfo.GetDrives
            With drive
                If .IsReady Then
                    dr.Append(drive.Name & ";")
                End If
            End With
        Next
        Return dr.ToString
    End Function

    Private Function ReplaceFilter(ByVal sFilter As String) As String
        sFilter = sFilter.Replace("+", "\+")
        sFilter = sFilter.Replace(".", "\.")
        sFilter = sFilter.Replace("|", "\|")
        sFilter = sFilter.Replace(";", "|\b")
        sFilter = sFilter.Replace(" ", "|\b")
        sFilter = sFilter.Replace("{", "\{")
        sFilter = sFilter.Replace("}", "\}")
        sFilter = sFilter.Replace("*", ".+")
        sFilter = sFilter.Replace("?", ".{1}")
        sFilter = sFilter.Replace("(", "\(")
        sFilter = sFilter.Replace(")", "\)")
        sFilter = sFilter.Replace("^", "\^")
        sFilter = sFilter.Replace("$", "\$")
        sFilter = sFilter.Replace("[", "\[")
        sFilter = sFilter.Replace("[", "\]")

        Do While CBool(InStr(sFilter, "|\b|\b"))
            sFilter = Replace$(sFilter, "|\b|\b", "|\b")
        Loop
        Return "^(" & sFilter & ")$|(" & sFilter & ".+)"
    End Function


    Public Function NormalizePath(byval sData As String) As String

        If Strings.Len(sData) > 1 Then
            sData = Strings.Replace(sData, "/", "\")
            If Not Strings.Right(sData, 1) = "\" Then
                Return sData & "\"
            Else
                Return sData
            End If
        End If

    End Function


#End Region

#Region " propiedades "
    Private p_match As String = String.Empty

    WriteOnly Property Match() As String
        Set(ByVal value As String)
            p_match = ReplaceFilter(value)
        End Set
    End Property

    Private p_subfolder As Boolean = False
    Property SubFolder() As Boolean
        Get
            Return p_subfolder
        End Get
        Set(ByVal value As Boolean)
            p_subfolder = value
        End Set
    End Property
    Private p_hide As Boolean = False
    Property HideFolder() As Boolean
        Get
            Return p_hide
        End Get
        Set(ByVal value As Boolean)
            p_hide = value
        End Set
    End Property
    Private p_sys As Boolean = False
    Property SysFolder() As Boolean
        Get
            Return p_sys
        End Get
        Set(ByVal value As Boolean)
            p_sys = value
        End Set
    End Property
    Private p_path As String = drivers()
    Property Path() As String
        Get
            Return p_path
        End Get
        Set(ByVal value As String)
       
            p_path = NormalizePath(value)
        End Set
    End Property
    ReadOnly Property FilesString() As String
        Get
            Return sbFolders.ToString
        End Get
    End Property

    ReadOnly Property FolderString() As String
        Get

            Return sbFolders.ToString
        End Get
    End Property
#End Region

End Class

Novlucker

El código no está mal pero ... si miras el código interno de IO.Directory.GetFiles verás que hace uso de la siguiente clase, y de las mismas API
Código (vbnet) [Seleccionar]
<Serializable, StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto), BestFitMapping(False)> _
Friend Class WIN32_FIND_DATA
    Friend dwFileAttributes As Integer
    Friend ftCreationTime_dwLowDateTime As UInt32
    Friend ftCreationTime_dwHighDateTime As UInt32
    Friend ftLastAccessTime_dwLowDateTime As UInt32
    Friend ftLastAccessTime_dwHighDateTime As UInt32
    Friend ftLastWriteTime_dwLowDateTime As UInt32
    Friend ftLastWriteTime_dwHighDateTime As UInt32
    Friend nFileSizeHigh As Integer
    Friend nFileSizeLow As Integer
    Friend dwReserved0 As Integer
    Friend dwReserved1 As Integer
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
    Friend cFileName As String
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> _
    Friend cAlternateFileName As String
    <TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")> _
    Public Sub New()
End Class


Saludos :P
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein