Por este listado específico, el siguiente código hará:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/");
request.Credentials = new NetworkCredential("user", "password");
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream());
string pattern =
@"^([\w-]+)\s+(\d+)\s+(\w+)\s+(\w+)\s+(\d+)\s+" +
@"(\w+\s+\d+\s+\d+|\w+\s+\d+\s+\d+:\d+)\s+(.+)$";
Regex regex = new Regex(pattern);
IFormatProvider culture = CultureInfo.GetCultureInfo("en-us");
string[] hourMinFormats =
new[] { "MMM dd HH:mm", "MMM dd H:mm", "MMM d HH:mm", "MMM d H:mm" };
string[] yearFormats =
new[] { "MMM dd yyyy", "MMM d yyyy" };
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
Match match = regex.Match(line);
string permissions = match.Groups[1].Value;
int inode = int.Parse(match.Groups[2].Value, culture);
string owner = match.Groups[3].Value;
string group = match.Groups[4].Value;
long size = long.Parse(match.Groups[5].Value, culture);
DateTime modified;
string s = Regex.Replace(match.Groups[6].Value, @"\s+", " ");
if (s.IndexOf(':') >= 0)
{
modified = DateTime.ParseExact(s, hourMinFormats, culture, DateTimeStyles.None);
}
else
{
modified = DateTime.ParseExact(s, yearFormats, culture, DateTimeStyles.None);
}
string name = match.Groups[7].Value;
Console.WriteLine(
"{0,-16} permissions = {1} size = {2, 9} modified = {3}",
name, permissions, size, modified.ToString("yyyy-MM-dd HH:mm"));
}
obtendrá (a partir del año 2016):
bin permissions = d--x--x--x size = 4096 modified = 2002-03-07 00:00
TEST.TXT permissions = -rw-r--r-- size = 659450 modified = 2016-06-15 05:07
TEST03-05.TXT permissions = -rw-r--r-- size = 101786380 modified = 2008-09-08 00:00
dropoff permissions = drwxrwxr-x size = 4096 modified = 2016-05-06 12:24
Pero, en realidad, intentar analizar la lista devuelta por ListDirectoryDetails
no es el camino correcto.
Desea utilizar un cliente FTP que admita el comando MLSD
moderno que devuelve un listado de directorios en un formato legible por máquina especificado en el RFC 3659. El análisis del formato legible por humanos devuelto por el antiguo comando LIST
(utilizado internamente por FtpWebRequest
para su método ListDirectoryDetails
) debe utilizarse como la opción de último recurso, cuando se habla con servidores FTP obsoletos, que no admiten el comando MLSD
(como Microsoft Servidor FTP de IIS).
Muchos servidores utilizan un formato diferente para la respuesta del comando LIST
. Particularmente, IIS puede usar el formato DOS. Ver C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response.
Por ejemplo, con WinSCP .NET assembly, puede utilizar sus Session.ListDirectory
o Session.EnumerateRemoteFiles
métodos.
Utilizan internamente el comando MLSD
, pero pueden recurrir al comando LIST
y admiten docenas de diferentes formatos de listas legibles por humanos.
El listado devuelto se presenta como colección de RemoteFileInfo
instances con propiedades como:
Name
LastWriteTime
(con zona horaria correcta)
Length
FilePermissions
(analizado en los derechos individuales)
Group
Owner
IsDirectory
IsParentDirectory
IsThisDirectory
(yo soy el autor de WinSCP)
mayoría de las otras bibliotecas 3 ª parte harán lo mismo. El uso del FtpWebRequest
class no es confiable para este propósito. Desafortunadamente, no hay otro cliente FTP incorporado en .NET Framework.
Gran Regex, añadido los nombres de toda la capturar grupos para hacerlo más difícil de entender al analizar ... ¿Cómo muestra el ftpd que usa este formato años en la fecha de modificación? – ullmark
si el año de la fecha de modificación es el año actual, entonces muestra solo el dm de MMM y hh: mm, pero si es de un año anterior, muestra el año real, pero no el tiempo. –
Con los grupos:.?? ^ (? [d -]) (? [rwxt -] {3}) {3} \ s + \ d {1,} \ s + * ( \ d {1, }) \ s + (? \ w + \ s + \ d {1,2} \ s + (?: \ d {4})?) (? \ d {1,2}: \ d {2})? \ s + (? . +?) \ s? $ Si el año es el mismo, se mostrará la hora, de lo contrario, se mostrará el año. Eso es por diseño. Si necesita una marca de tiempo precisa, use WebRequestMethods.Ftp.GetDateTimestamp. –
adzm