Per questa offerta specifica, il seguente codice farà:
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"));
}
otterrete (come del 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
Ma, in realtà, cercare di analizzare l'elenco restituito dal ListDirectoryDetails
non è la strada giusta da percorrere.
Si desidera utilizzare un client FTP che supporta il moderno comando MLSD
che restituisce un elenco di directory in un formato leggibile dalla macchina specificato nello RFC 3659. L'analisi del formato leggibile dall'uomo restituito dal comando antico LIST
(utilizzato internamente dal FtpWebRequest
per il suo metodo ListDirectoryDetails
) deve essere utilizzato come ultima opzione, quando si parla di server FTP obsoleti, che non supportano il comando MLSD
(come Microsoft Server FTP IIS).
Molti server utilizzano un formato diverso per la risposta del comando LIST
. In particolare, IIS può utilizzare il formato DOS. Vedi C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response.
Ad esempio, con WinSCP .NET assembly, è possibile utilizzare le sue Session.ListDirectory
o Session.EnumerateRemoteFiles
metodi.
Essi utilizzano internamente il comando MLSD
, ma possono ricorrere al comando LIST
e supportare dozzine di diversi formati di elenchi leggibili dall'uomo.
L'elenco restituito viene presentata come insieme di RemoteFileInfo
instances con immobili come:
Name
LastWriteTime
(con il corretto fuso orario)
Length
FilePermissions
(analizzato in diritti individuali)
Group
Owner
IsDirectory
IsParentDirectory
IsThisDirectory
(io sono l'autore di WinSCP)
La maggior parte delle altre biblioteche 3rd party faranno lo stesso. L'utilizzo di FtpWebRequest
class non è affidabile per questo scopo. Sfortunatamente, non ci sono altri client FTP integrati nel framework .NET.
Grande Regex, nomi aggiunto per tutto il catturare gruppi per renderlo più inespugnabile durante l'analisi ... Come fa il ftpd che usa questo formato per mostrare anni nella data di modifica? – ullmark
se l'anno della data di modifica è l'anno corrente, quindi mostra solo il MMM dd e hh: mm, ma se è relativo a un anno precedente, quindi mostra l'anno effettivo, ma non il tempo. –
Con i gruppi:?? ^ (? [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? $ Se l'anno è lo stesso, allora mostrerà il tempo, altrimenti mostrerà l'anno. Questo è di design. Se è necessario un timestamp accurato, utilizzare WebRequestMethods.Ftp.GetDateTimestamp. –
adzm