Parsing FtpWebRequest ListDirectoryDetails line
Not sure if you still need this, but this is the solution i came up with:
Regex regex = new Regex ( @"^([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?$",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace );
Match Groups:
- object type:
- d : directory
- - : file
- Array[3] of permissions (rwx-)
- File Size
- Last Modified Date
- Last Modified Time
- File/Directory Name
C# class to parse WebRequestMethods.Ftp.ListDirectoryDetails FTP response
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).
How to parse this? ftpWebRequest ListDirectorDetials
var value = "09-17-11 01:00AM 942038 my.zip";
var tokens = value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length > 3)
{
var test = new Test
{
DateCreated = DateTime.ParseExact(tokens[0] + tokens[1], "MM-dd-yyHH:mmtt", CultureInfo.InvariantCulture),
Size = int.Parse(tokens[2]),
Name = tokens[3]
};
// at this stage:
// test.DateCreated = 17/09/2011 01:00AM
// test.Size = 942038
// test.Name = "my.zip"
}
How to read the creation date from a string[] with FTP ListDirectoryDetails?
Not really an answer to the question, but at first I ended up with making a separate call to the FTP server to get the LastModified
datetime of the file(not a good solution) and added them to a list of file names with creation dates.
In the end it turned out that the creation date of the file is no longer important for the project, so I just used the standard FTP ListDirectory
.
Extracting file names from WebRequestMethods.Ftp.ListDirectoryDetails
The final solution was to use regex and split it using groups. This resolved all issues and allowed me to get the file / directory name and whether it was a directory or file.
string regex =
@"^" + //# Start of line
@"(?<dir>[\-ld])" + //# File size
@"(?<permission>[\-rwx]{9})" + //# Whitespace \n
@"\s+" + //# Whitespace \n
@"(?<filecode>\d+)" +
@"\s+" + //# Whitespace \n
@"(?<owner>\w+)" +
@"\s+" + //# Whitespace \n
@"(?<group>\w+)" +
@"\s+" + //# Whitespace \n
@"(?<size>\d+)" +
@"\s+" + //# Whitespace \n
@"(?<month>\w{3})" + //# Month (3 letters) \n
@"\s+" + //# Whitespace \n
@"(?<day>\d{1,2})" + //# Day (1 or 2 digits) \n
@"\s+" + //# Whitespace \n
@"(?<timeyear>[\d:]{4,5})" + //# Time or year \n
@"\s+" + //# Whitespace \n
@"(?<filename>(.*))" + //# Filename \n
@"$"; //# End of line
var split = new Regex(regex).Match(line);
string dir = split.Groups["dir"].ToString();
string filename = split.Groups["filename"].ToString();
bool isDirectory = !string.IsNullOrWhiteSpace(dir) && dir.Equals("d", StringComparison.OrdinalIgnoreCase);
Thanks to: http://blogs.msdn.com/b/adarshk/archive/2004/09/15/sample-code-for-parsing-ftpwebrequest-response-for-listdirectorydetails.aspx for providing the regex.
Parsing file name out of ListDirectoryDetails with Regex
To parse out just a filename, just get the 9th token:
^(?:[^ ]+ +){8}(.*)$
Regex regex = new Regex("^(?:[^ ]+ +){8}(.*)$");
Match match = regex.Match(line);
string filename = match.Groups[1].Value;
Though for such a simple parsing, you can actually split the line to tokens by space. You do not need a regular expression.
string[] tokens = line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
string filename = tokens[8];
But if you need just a file name, do not use the ListDirectoryDetails
in the first place. Use the ListDirectory
. It returns file name only.
And if you need parsing file attributes, use an FTP client that supports the FTP MLSD
command. The FtpWebRequest
does not support this.
FtpWebRequest only return file names with ListDirectoryDetails
The method to get object names of ftp always return the complete list (directories and files). I limit the names by extension, for example
var xmlFiles = files.FindAll( foo => foo.ToUpper().Contains( ".XML" )|| foo.ToUpper().Contains( ".TXT" ));
Related Topics
Memory Allocation: Stack VS Heap
Getting Type T from Ienumerable<T>
How to Filter "Include" Entities in Entity Framework
Difference Between Invoke and Dynamicinvoke
How to Call a Non-Static Method from a Static Method in C#
Timeouts with Long Running ASP.NET MVC Core Controller Httppost Method
Calling Async Methods from a Wcf Service
Entity Framework 4 Delete Object from Entity Collection
The Name 'Configurationmanager' Does Not Exist in the Current Context
Determine If a Sequence Contains All Elements of Another Sequence Using Linq
Strip the Byte Order Mark from String in C#
External JSON Vulnerable Because of JSON.Net Typenamehandling Auto
Differencebetween Using Idisposable VS a Destructor in C#
Servicestack Rest API and Cors
How to Get Command Line Arguments of Other Processes from .Net/C#