none
Buscar archivo por una cadena RRS feed

  • Pregunta

  • Buenos días,

    Pongamos que en un formulario tengo una caja de texto TextBox1, y un botón Button1 con el texto Buscar. Al pulsar el botón quiero que me haga la búsqueda, por ejemplo a partir de la carpeta "Mis documentos", de los archivos que contengan la cadena de texto que haya introducido en TextBox1. Es decir: si busco por la palabra "casi", que me encuentre "casi", o "casimiro", o "encasillado"o ... pero no encuentro el método adecuado para hacerlo.

    Agradeceré todas las respuestas.

    jueves, 16 de marzo de 2017 13:28

Respuestas

  • Odisea 2001,

    Basta con cambiar la opción -del enumerador SearchOption- a AllDirectories en vez de 'TopDirectoryOnly'. Sin embargo, si las carpetas subyacentes a la carpeta "origen" se encuentran protegidas y el usuario no tiene los permisos necesarios de lectura entonces obtendrás la excepción 'System.UnauthorizedAccessException'. De darse el caso puedes escribir soluciones "paleativas" bajo la recomendación de los siguientes enlaces:

    UnauthorizedAccessException

    Directory.EnumerateFiles => UnauthorizedAccessException


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta Odisea 2001 viernes, 17 de marzo de 2017 16:48
    jueves, 16 de marzo de 2017 17:53

Todas las respuestas

  • Odisea 2001,

    Debes establecer un patrón de búsqueda combinando el texto ingresado y caracteres comodín (*/?) (wilcard), por ejemplo:

    if (!string.IsNullOrEmpty(textBox1.Text)) //¿La propiedad Text contiene caracteres?
    {
    	string nombreArchivo = string.Format("*{0}*", textBox1.Text); //Patrón de búsqueda
    	string extensionArchivo = "*"; //Patrón de búsqueda para la extensión del archivo
    
    	foreach (var item in Directory.GetFiles(
    		Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
    		string.Format("{0}.{1}", nombreArchivo, extensionArchivo),
    		SearchOption.TopDirectoryOnly))
    	{
    		lbxArchivos.Items.Add(Path.GetFileName(item)); //Ver el resultado en un ListBox
    	}
    }


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Propuesto como respuesta Sergio Parra jueves, 16 de marzo de 2017 15:34
    jueves, 16 de marzo de 2017 15:13
  • Debes de agregar un elemento en el cual puedas listar todos los resultados

    Como un ListBox o un datagridview

    Por ejemplo:

    (folderPath puedes ingresarla por medio de una FolderBrowserDialog(esto es un control))

    Private Sub ListFiles(ByVal folderPath As String)
            filesListBox.Items.Clear()
    
            Dim fileNames = My.Computer.FileSystem.GetFiles(
                folderPath, FileIO.SearchOption.SearchTopLevelOnly, "*.txt")
    
            For Each fileName As String In fileNames
                filesListBox.Items.Add(fileName)
            Next
        End Sub

    Saludos cordiales


    William Lickez

    jueves, 16 de marzo de 2017 15:14
  • Hola Williams

    La respuesta que me envías creo que está en lenguaje C, porque no mencioné que estoy haciendo el programa en vb net, y no he sido capaz de traducirlo para probar si me funciona esa solución. ¿Podrías traducirlo a vb?

    Gracias

    jueves, 16 de marzo de 2017 16:12
  • La respuesta que te han dado antes busca los archivos cuyo NOMBRE contenga el texto deseado. Pero si quieres los archivos cuyo CONTENIDO incluya el texto deseado, entonces tienes que abrir cada uno de los archivos, leer el contenido y buscar la cadena en ese contenido. Evidentemente, sera muy costoso si hay muchos archivos o son muy grandes, y no funcionara con los archivos que no sean de tipo "texto".

    Una forma sencilla (pero no muy eficiente) de hacer la busaqueda es esta:

    using System.IO;
    //...
    string[] ficheros = Directory.GetFiles(carpeta);
    foreach (string fichero in ficheros)
    {
        string contenido = File.ReadAllText(fichero);
        if (contenido.Contains(textBox1.Text)
        {
            // Este fichero contiene el texto deseado
        }
    }
    
    Notese que esta comparacion es sensible a mayusculas. Si la quieres insensible, puedes poner .ToLower() en los dos lados de la comparacion.

    jueves, 16 de marzo de 2017 16:17
  • Hola Alberto

    Como le decía a Williams, la respuesta que me envías creo que está en lenguaje C, porque no mencioné que estoy haciendo el programa en vb net, y no he sido capaz de traducirlo para probar si me funciona esa solución. ¿Podrías traducirlo a vb?

    Estaba buscando que el texto formara parte del nombre del archivo, pero anoto esta otra solución para el contenido, porque puede ser también de utilidad, también una vez que se pueda traducir a vb net.

    Gracias

    jueves, 16 de marzo de 2017 16:57
  • Odisea 2001,

    If Not String.IsNullOrEmpty(TextBox1.Text) Then	'¿La propiedad Text contiene caracteres?
    	Dim nombreArchivo As String = String.Format("*{0}*", TextBox1.Text) 'Patrón de búsqueda
    	Dim extensionArchivo As String = "*" 'Patrón de búsqueda para la extensión del archivo
    	For Each item As String In System.IO.Directory.GetFiles(
    		Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
    		String.Format("{0}.{1}", nombreArchivo, extensionArchivo),
    		System.IO.SearchOption.TopDirectoryOnly)
    
    		'Ver el resultado en un ListBox
    		lbxArchivos.Items.Add(System.IO.Path.GetFileName(item))
    	Next
    End If

    Puedes utilizar algún servicio para convertir código de c# a Visual Basic o viceversa como Converter Telerik


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    jueves, 16 de marzo de 2017 17:14
  • Hola William

    He agregado los controles, y el código según tus instrucciones, y me encuentra los archivos con el texto de búsqueda, pero sólo si selecciono la carpeta en la que sé que están.

    Lo que yo quería hacer, es que busque en todas las carpetas contenidas en una de inicio, es decir: si de la carpeta Mis Documentos cuelgan documentos sueltos, y otras tres carpetas, quiero buscar en los documentos sueltos y en los documentos contenidos en esas tres carpetas. 

    Envío el código para ver si me dices lo que no hago bien.

         Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If FolderBrowserDialog1.ShowDialog() = DialogResult.OK Then
                TextBox1.Text = FolderBrowserDialog1.SelectedPath
                ListFiles(TextBox1.Text)
            End If
        End Sub

        Private Sub ListFiles(ByVal folderPath As String)
            filesListBox.Items.Clear()
            TextBox1.Text = "*casi*"
            Dim fileNames = My.Computer.FileSystem.GetFiles _
                            (folderPath, FileIO.SearchOption.SearchTopLevelOnly, TextBox1.Text)
            For Each fileName As String In fileNames
                filesListBox.Items.Add(fileName)
            Next
        End Sub

    Gracias y saludos.

    jueves, 16 de marzo de 2017 17:27
  • Odisea 2001,

    Basta con cambiar la opción -del enumerador SearchOption- a AllDirectories en vez de 'TopDirectoryOnly'. Sin embargo, si las carpetas subyacentes a la carpeta "origen" se encuentran protegidas y el usuario no tiene los permisos necesarios de lectura entonces obtendrás la excepción 'System.UnauthorizedAccessException'. De darse el caso puedes escribir soluciones "paleativas" bajo la recomendación de los siguientes enlaces:

    UnauthorizedAccessException

    Directory.EnumerateFiles => UnauthorizedAccessException


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta Odisea 2001 viernes, 17 de marzo de 2017 16:48
    jueves, 16 de marzo de 2017 17:53
  • Hola Alberto [...] ¿Podrías traducirlo a vb?

    Para otra vez que te pase esto, puedes usar uno de los muchos convertidores automáticos que hay, como por ejemplo este:

    http://www.carlosag.net/Tools/CodeTranslator/

    Imports System.IO
    '...
    Dim ficheros() As String = Directory.GetFiles(carpeta)
    For Each fichero As String In ficheros
        Dim contenido As String = File.ReadAllText(fichero)
        If contenido.Contains(textBox1.Text) Then
            ' Este fichero contiene el texto deseado
        End If
    Next

    jueves, 16 de marzo de 2017 18:39
  • Buenos días, Alberto

    No se me había ocurrido buscar un traductor, pero tomo nota para sucesivas ocasiones.

    A la solución que me envíaste, le añadí un explorador de carpetas, y, efectivamente, me encuentra el texto buscado. Lo que yo no encuentro después de haber desplegado los métodos y propiedades de “ficheros” y de “contenido” es cómo puedo capturar el path del archivo en el que he encontrado el texto de búsqueda. Te agradeceré que me aclares ese detalle para cerrar la conversación.

    Saludos 

     

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

            Dim CarpetaDir As String = String.Empty

            If FolderBrowserDialog1.ShowDialog() = DialogResult.OK Then

                CarpetaDir = FolderBrowserDialog1.SelectedPath

            End If

            Dim ficheros() As String = Directory.GetFiles(CarpetaDir)

            txtResumen.Text = "*casi*"

            For Each fichero As String In ficheros

                Dim contenido As String = File.ReadAllText(fichero)

                If contenido.Contains(TextBox1.Text) Then

                    MsgBox("Este fichero contiene el texto deseado ")

                End If

            Next

        End Sub

    viernes, 17 de marzo de 2017 8:31
  • Buenos días, Willams

    No se me había ocurrido buscar un traductor, pero tomo nota para sucesivas ocasiones.

    A la solución que me envíaste le debe de faltar algo, porque no devuelve errores pero tampoco me encuentra ningún archivo. Copio el código completo para que lo puedas revisar.

    Gracias y saludos

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

            txtResumen.Text = "*estru*"

            If Not String.IsNullOrEmpty(TextBox1.Text) Then '¿La propiedad Text contiene caracteres?

                Dim nombreArchivo As String = String.Format("*{0}*", TextBox1.Text) 'Patrón de búsqueda

                Dim extensionArchivo As String = "*" 'Patrón de búsqueda para la extensión del archivo

                For Each item As String In System.IO.Directory.GetFiles(Environment.GetFolderPath _

                                                        (Environment.SpecialFolder.MyDocuments), _

                                                        String.Format("{0}.{1}", nombreArchivo, extensionArchivo), _

                                                        System.IO.SearchOption.TopDirectoryOnly)

                    filesListBox.Items.Add(System.IO.Path.GetFileName(item))

                Next

            End If

        End Sub

    viernes, 17 de marzo de 2017 8:34
  • [...] los métodos y propiedades de “ficheros” y de “contenido” es cómo puedo capturar el path del archivo en el que he encontrado el texto de búsqueda

    El path del archivo es precisamente el contenido la variable "fichero" (en singular), de tipo string, es decir, no hay que tomar ninguna propiedad, sino que el propio string fuardado en fichero ya representa el path.

    viernes, 17 de marzo de 2017 9:31
  • Odisea 2001,

    Es posible que el objeto TextBox1 (que contiene -para el ejemplo- la cadena a buscar) se encuentre vacío, entiendo que el nombre del objeto debería ser txtResumen (haz el cambio en todo lugar que aparezca el objeto TextBox1):

    txtResumen.Text = "*estru*"
    If Not String.IsNullOrEmpty(txtResumen.Text) Then

    Por otro lado, fíjate que la variable nombreArchivo contiene la cadena a buscar agregando el comodín *, por tanto puedes evitar escribir los comodines en el cuadro de texto o bien quitarlo de la definición en la variable nombreArchivo.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    viernes, 17 de marzo de 2017 14:39
  • Hola Alberto

    No he mirado el código con la suficiente atención.

    Mis disculpas y muchas gracias

    viernes, 17 de marzo de 2017 16:36
  • Hola Wiliams,

    He verificado en ejecución que la variable tiene contenido, pero no me encuentra nada.

    No obstante, la solución que sí funciona para mis propósitos es aquella otra en la que ayer me aconsejabas "Basta con cambiar la opción -del enumerador SearchOption- a AllDirectories en vez de 'TopDirectoryOnly'"que además es mucho más sencilla para mi. De modo que será esa la que marque como Respuesta para cerrar este hilo.

    Muchas gracias por tu atención.

    viernes, 17 de marzo de 2017 16:48