2008-09-23 14 views

Respuesta

27

Algunas consideraciones importantes antes del código:

  1. El servidor HTTP tiene que ser configurado para permitir directorios listado para los directorios que desee;
  2. Como las listas de directorios son páginas HTML normales, no existe un estándar que defina el formato de una lista de directorios;
  3. Debido a la consideración usted está en la tierra donde tiene que poner un código específico para cada servidor.

Mi elección es usar expresiones regulares. Esto permite un rápido análisis y personalización. Puede obtener un patrón específico de expresiones regulares por sitio y así tener un enfoque muy modular. Utilice una fuente externa para mapear URL a patrones de expresiones regulares si planea mejorar el módulo de análisis con la compatibilidad con nuevos sitios sin cambiar el código fuente.

Ejemplo para imprimir el listado de directorios de http://www.ibiblio.org/pub/

namespace Example 
{ 
    using System; 
    using System.Net; 
    using System.IO; 
    using System.Text.RegularExpressions; 

    public class MyExample 
    { 
     public static string GetDirectoryListingRegexForUrl(string url) 
     { 
      if (url.Equals("http://www.ibiblio.org/pub/")) 
      { 
       return "<a href=\".*\">(?<name>.*)</a>"; 
      } 
      throw new NotSupportedException(); 
     } 
     public static void Main(String[] args) 
     { 
      string url = "http://www.ibiblio.org/pub/"; 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
      using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
      { 
       using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
       { 
        string html = reader.ReadToEnd(); 
        Regex regex = new Regex(GetDirectoryListingRegexForUrl(url)); 
        MatchCollection matches = regex.Matches(html); 
        if (matches.Count > 0) 
        { 
         foreach (Match match in matches) 
         { 
          if (match.Success) 
          { 
           Console.WriteLine(match.Groups["name"]); 
          } 
         } 
        } 
       } 
      } 

      Console.ReadLine(); 
     } 
    } 
} 
8

comprensión básica:

listados de directorio son sólo las páginas HTML generadas por un servidor web. Cada servidor web genera estas páginas HTML a su manera porque no hay una forma estándar para que un servidor web liste estos directorios.

La mejor manera de obtener una lista de directorios es simplemente hacer una solicitud HTTP a la URL que desea que aparezca en el directorio, y tratar de analizar y extraer todos los enlaces del HTML que se le devuelve.

Para analizar los enlaces HTML, intente utilizar el HTML Agility Pack.

Examen de directorios:

El servidor web que le gustaría a la lista de directorios deben tener la navegación de directorios activada para obtener esta representación HTML de los archivos en sus directorios. Por lo tanto, solo puede obtener la lista de directorios si el servidor HTTP desea que usted pueda.

Un ejemplo rápido de la agilidad del paquete de HTML:

HtmlDocument doc = new HtmlDocument(); 
doc.Load(strURL); 
foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//[email protected]") 
{ 
HtmlAttribute att = link"href"; 
//do something with att.Value; 
} 

Limpiador alternativa:

Si es posible, en su situación, un método más limpio es el uso de un protocolo previsto para el directorio listados, como el Protocolo de transferencia de archivos (FTP), SFTP (como FTP sobre SSH) o FTPS (FTP sobre SSL).

¿Qué pasa si la exploración de directorios no está encendido:

Si el servidor web no tiene la exploración de directorios activada, entonces no hay manera fácil de obtener el listado del directorio.

Lo mejor que puede hacer en este caso es comenzar en una URL determinada, seguir todos los enlaces HTML en la misma página y tratar de crear una lista virtual de directorios basándose en las rutas relativas de los recursos en estos HTML páginas. Sin embargo, esto no le dará una lista completa de qué archivos están realmente en el servidor web.

0

No puede, a menos que el directorio en particular que desea tenga habilitada la lista de directorios y no haya ningún archivo predeterminado (generalmente index.htm, index.html o default.html pero siempre configurable). Solo entonces se te presentará una lista de directorios, que generalmente estará marcada con HTML y requerirá un análisis sintáctico.

0

Puede configurar el servidor como alternativa para WebDAV.

2

Gracias por la gran publicación. para mí, el patrón a continuación funcionó mejor.

<AHREF=\\"\S+\">(?<name>\S+)</A> 

También lo probé en http://regexhero.net/tester.

a utilizarlo en su código C#, hay que añadir más barras invertidas() antes de cualquier barra invertida y comillas dobles en el patrón para i

<AHREF=\\"\S+\">(?<name>\S+)</A>

nstance, en el método GetDirectoryListingRegexForUrl debe usar algo como esto

return "< A HREF = \\" \ S + \\ "> (? \ S +)";

¡Salud!

+0

Muchas gracias. Ahorró tiempo. –

4

i acaba de modificar arriba y pareció que esta mejor

public static class GetallFilesFromHttp 
{ 
    public static string GetDirectoryListingRegexForUrl(string url) 
    { 
     if (url.Equals("http://ServerDirPath/")) 
     { 
      return "\\\"([^\"]*)\\\""; 
     } 
     throw new NotSupportedException(); 
    } 
    public static void ListDiractory() 
    { 
     string url = "http://ServerDirPath/"; 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
     using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
     { 
      using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
      { 
       string html = reader.ReadToEnd(); 

       Regex regex = new Regex(GetDirectoryListingRegexForUrl(url)); 
       MatchCollection matches = regex.Matches(html); 
       if (matches.Count > 0) 
       { 
        foreach (Match match in matches) 
        { 
         if (match.Success) 
         { 
          Console.WriteLine(match.ToString()); 
         } 
        } 
       } 
      } 
      Console.ReadLine(); 
     } 
    } 
} 
1

El siguiente código funciona bien para mí cuando yo no tengo acceso al servidor ftp:

public static string[] GetFiles(string url) 
{ 
    List<string> files = new List<string>(500); 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
    { 
     using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
     { 
      string html = reader.ReadToEnd(); 

      Regex regex = new Regex("<a href=\".*\">(?<name>.*)</a>"); 
      MatchCollection matches = regex.Matches(html); 

      if (matches.Count > 0) 
      { 
       foreach (Match match in matches) 
       { 
        if (match.Success) 
        { 
         string[] matchData = match.Groups[0].ToString().Split('\"'); 
         files.Add(matchData[1]); 
        } 
       } 
      } 
     } 
    } 
    return files.ToArray(); 
} 

Sin embargo, cuando Tengo acceso al servidor ftp, el siguiente código funciona mucho más rápido:

public static string[] getFtpFolderItems(string ftpURL) 
{ 
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpURL); 
    request.Method = WebRequestMethods.Ftp.ListDirectory; 

    //You could add Credentials, if needed 
    //request.Credentials = new NetworkCredential("anonymous", "password"); 

    FtpWebResponse response = (FtpWebResponse)request.GetResponse(); 

    Stream responseStream = response.GetResponseStream(); 
    StreamReader reader = new StreamReader(responseStream); 

    return reader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
} 
Cuestiones relacionadas