I'm creating a service to monitor FTP locations for new updates and require the ability to parse the response returned from a FtpWebRequest response using the WebRequestMethods.Ftp.ListDirectoryDetails method. It would be fairly easy if all responses followed the same format, but different FTP server software provide different response formats.
For example one might return:
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
And another server might return:
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
And other differences have been observed also so there's likely to be a number of subtle differences I haven't encountered yet.
Does anyone know of a fully managed (doesn't require access to external dll on Windows) C# class that handles these situations seamlessly?
I only need to list the contents of a directory with the following details: File/directory name, last updated or created timestamp, file/directory name.
Thanks in advance for any suggestions, Gavin
For the first (DOS/Windows) listing this code will do:
You will get:
For the other (*nix) listing, see my answer to Parsing FtpWebRequest ListDirectoryDetails line.
But, actually trying to parse the listing returned by the
ListDirectoryDetails
is not the right way to go.You want to use an FTP client that supports the modern
MLSD
command that returns a directory listing in a machine-readable format specified in the RFC 3659. Parsing the human-readable format returned by the ancientLIST
command (used internally by theFtpWebRequest
for itsListDirectoryDetails
method) should be used as the last resort option, when talking to obsolete FTP servers, that do not support theMLSD
command (like the Microsoft IIS FTP server).For example with WinSCP .NET assembly, you can use its
Session.ListDirectory
orSession.EnumerateRemoteFiles
methods.They internally use the
MLSD
command, but can fall back to theLIST
command and support dozens of different human-readable listing formats.The returned listing is presented as collection of
RemoteFileInfo
instances with properties like:Name
LastWriteTime
(with correct timezone)Length
FilePermissions
(parsed into individual rights)Group
Owner
IsDirectory
IsParentDirectory
IsThisDirectory
(I'm the author of WinSCP)
Most other 3rd party libraries will do the same. Using the
FtpWebRequest
class is not reliable for this purpose. Unfortunately, there's no other built-in FTP client in the .NET framework.I'm facing this same problem and have built a simple (albeit not very robust) solution using a Regex to parse out the relevant information from each line using capture groups:
You can then extract the values out of the capture groups by:
Some things not note are:
ftpResponse
variable above. In my case I'm lucky to only be accessing the same FTP server each time and so it is unlikely that the response format will change.yearTime
variable can represent EITHER the year or the time of the file's timestamp. You will need to parse this manually by looking for an instance of the colon : character which will indicate that this capture group contains a time rather than the yearTake a look at Ftp.dll FTP client.
It includes automatic directory listing parser for most FTP servers on Windows, Unix and Netware platforms.
Please note that this is a commercial product I developed.
One solution I came across is EdtFTPnet
EdtFTPnet seems to be quite a feature packed solution that handles lots of different FTP options so is ideal.
It's the free open source solution that I've how employed for http://www.ftp2rss.com (a little tool I needed myself but figured might be useful to others also).