it-swarm.com.de

C # -Klasse zum Analysieren der WebRequestMethods.Ftp.ListDirectoryDetails-FTP-Antwort

Ich erstelle einen Dienst zum Überwachen von FTP-Speicherorten auf neue Updates und möchte, dass die von einer FtpWebRequest - Antwort zurückgegebenen Antworten mithilfe der WebRequestMethods.Ftp.ListDirectoryDetails -Methode analysiert werden. Es wäre ziemlich einfach, wenn alle Antworten dasselbe Format hätten, aber unterschiedliche FTP-Server-Software unterschiedliche Antwortformate bieten.

Zum Beispiel könnte man zurückgeben:

08-10-11  12:02PM       <DIR>          Version2
06-25-09  02:41PM            144700153 image34.gif
06-25-09  02:51PM            144700153 updates.txt
11-04-10  02:45PM            144700214 digger.tif

Und ein anderer Server könnte zurückkehren:

d--x--x--x    2 ftp      ftp          4096 Mar 07  2002 bin
-rw-r--r--    1 ftp      ftp        659450 Jun 15 05:07 TEST.TXT
-rw-r--r--    1 ftp      ftp      101786380 Sep 08  2008 TEST03-05.TXT
drwxrwxr-x    2 ftp      ftp          4096 May 06 12:24 dropoff

Es wurden auch andere Unterschiede beobachtet, so dass es wahrscheinlich eine Reihe subtiler Unterschiede gibt, auf die ich noch nicht gestoßen bin.

Kennt jemand eine vollständig verwaltete (erfordert keinen Zugriff auf externe DLL unter Windows) C # -Klasse, die diese Situationen nahtlos behandelt?

Ich muss nur den Inhalt eines Verzeichnisses mit den folgenden Details auflisten: Datei-/Verzeichnisname, zuletzt aktualisierter oder erstellter Zeitstempel, Datei-/Verzeichnisname.

Vielen Dank im Voraus für alle Vorschläge, Gavin

20
Gavin

Eine Lösung, auf die ich gestoßen bin, ist EdtFTPnet

EdtFTPnet scheint eine sehr funktionsreiche Lösung zu sein, die viele verschiedene FTP-Optionen unterstützt und daher ideal ist.

Es ist die kostenlose Open-Source-Lösung, die ich für http://www.ftp2rss.com eingesetzt habe (ein kleines Tool, das ich selbst brauchte, das aber auch für andere nützlich sein könnte).

4
Gavin

Für die erste Auflistung (DOS/Windows) reicht dieser Code aus:

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 = @"^(\d+-\d+-\d+\s+\d+:\d+(?:AM|PM))\s+(<DIR>|\d+)\s+(.+)$";
Regex regex = new Regex(pattern);
IFormatProvider culture = CultureInfo.GetCultureInfo("en-us");
while (!reader.EndOfStream)
{
    string line = reader.ReadLine();
    Match match = regex.Match(line);
    DateTime modified =
       DateTime.ParseExact(
           match.Groups[1].Value, "MM-dd-yy  hh:mmtt", culture, DateTimeStyles.None);
    long size = (match.Groups[2].Value != "<DIR>") ? long.Parse(match.Groups[2].Value) : 0;
    string name = match.Groups[3].Value;

    Console.WriteLine(
        "{0,-16} size = {1,9}  modified = {2}",
        name, size, modified.ToString("yyyy-MM-dd HH:mm"));
}

Sie erhalten:

Version2         size =         0  modified = 2011-08-10 12:02
image34.gif      size = 144700153  modified = 2009-06-25 14:41
updates.txt      size = 144700153  modified = 2009-06-25 14:51
digger.tif       size = 144700214  modified = 2010-11-04 14:45

Für die andere (* nix) Auflistung siehe meine Antwort auf die Zeile Parsing FtpWebRequest ListDirectoryDetails .


Der Versuch, die von der ListDirectoryDetails zurückgegebene Auflistung zu analysieren, ist jedoch nicht der richtige Weg.

Sie möchten einen FTP-Client verwenden, der den modernen Befehl MLSD unterstützt, der eine Verzeichnisliste in einem in RFC 3659 angegebenen maschinenlesbaren Format zurückgibt. Wenn Sie mit veralteten FTP-Servern kommunizieren, die den Befehl LIST nicht unterstützen (z. B. Microsoft), sollten Sie als letzte Option das vom alten Befehl FtpWebRequest zurückgegebene lesbare Format verwenden (intern von der Methode ListDirectoryDetails für die Methode MLSD verwendet) IIS FTP-Server).


Mit WinSCP .NET Assembly können Sie beispielsweise die Methoden Session.ListDirectory oder Session.EnumerateRemoteFiles verwenden.

Sie verwenden intern den Befehl MLSD, können jedoch auf den Befehl LIST zurückgreifen und Dutzende von verschiedenen lesbaren Listenformaten unterstützen.

Die zurückgegebene Auflistung wird als Auflistung von RemoteFileInfo Instanzen mit folgenden Eigenschaften dargestellt:

  • Name
  • LastWriteTime (mit korrekter Zeitzone)
  • Length
  • FilePermissions (in individuelle Rechte zerlegt)
  • Group
  • Owner
  • IsDirectory
  • IsParentDirectory
  • IsThisDirectory

(Ich bin der Autor von WinSCP)


Die meisten anderen Bibliotheken von Drittanbietern tun dasselbe. Die Verwendung der Klasse FtpWebRequest ist für diesen Zweck nicht zuverlässig. Leider gibt es keinen anderen integrierten FTP-Client im .NET-Framework.

9
Martin Prikryl

Ich stehe vor dem gleichen Problem und habe eine einfache (wenn auch nicht sehr robuste) Lösung mit einem Regex erstellt, um die relevanten Informationen aus jeder Zeile mithilfe von Erfassungsgruppen zu analysieren:

public static Regex FtpListDirectoryDetailsRegex = new Regex(@".*(?<month>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\s*(?<day>[0-9]*)\s*(?<yearTime>([0-9]|:)*)\s*(?<fileName>.*)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

Sie können dann die Werte aus den Erfassungsgruppen extrahieren, indem Sie:

        string ftpResponse = "-r--r--r-- 1 ftp ftp              0 Nov 19 11:08 aaa.txt";
        Match match = FtpListDirectoryDetailsRegex.Match(ftpResponse);
        string month = match.Groups["month"].Value;
        string day = match.Groups["day"].Value;
        string yearTime = match.Groups["yearTime"].Value;
        string fileName = match.Groups["fileName"].Value;

Einige Dinge, die nicht beachtet werden, sind:

  • dies funktioniert nur für Verzeichnisantworten mit dem in der obigen Variablen ftpResponse beschriebenen Format. In meinem Fall habe ich das Glück, jedes Mal nur auf denselben FTP-Server zuzugreifen, und es ist daher unwahrscheinlich, dass sich das Antwortformat ändert.
  • die Variable yearTime kann entweder das Jahr oder die Uhrzeit des Zeitstempels der Datei darstellen. Sie müssen dies manuell analysieren, indem Sie nach einer Instanz des Doppelpunkts suchen: Zeichen, das angibt, dass diese Erfassungsgruppe eine Uhrzeit anstelle des Jahres enthält
7
calturk

Werfen Sie einen Blick auf Ftp.dll FTP-Client .

Es enthält Parser für die automatische Verzeichnisliste für die meisten FTP-Server unter Windows, Unix und Netware.

Bitte beachten Sie, dass dies ein kommerzielles Produkt ist, das ich entwickelt habe.

0