Extracting filenames from WebRequestMethods.Ftp.ListDirectoryDetails

I have an application that does the following: list directories, download file, download everything.

I have a problem getting file names from WebRequestMethods.Ftp.ListDirectoryDetails. It seems like this cannot be done for every scenario.

WebRequestMethods.Ftp.ListDirectoryDetails returns lineItem like this:

"- rw-r - r-- 1 ftp ftp 39979 Aug 01 16:02 db to pc 2014-08-05 07-30-00.csv"

I am using the first character to determine if it is a file or a directory. Then I split the file into space and get the filename after the fixed index amount in the split. The problem in my implementation is that if the file has multiple spaces then it would be wrong to reference fewer spaces and the file will not be found when trying to load it.

I cannot use split.last () as the filename may have spaces or WebRequestMethods.Ftp.ListDirectory as it prevents us from distinguishing between directory and file without extension. Also there is no regex as the filename can contain a date. Any help finding a solution that fully covers all cases would be great.

bool isDirectory = line.Substring(0,1).Equals("d", System.StringComparison.OrdinalIgnoreCase);

string[] itemNames = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).Select((value, index) => new { value, index }).Where(i => i.index > 7).Select(i => i.value).ToArray();
string val = string.Join(" ", itemNames);

      

+3


source to share


3 answers


The end solution was to use a regex and split it using groups. This solved all the problems and allowed me to get the name of the file / directory and whether it was a directory or a 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 regex.

+11


source


A simplified solution could be:



isDirectory=line[0]=='d'; 
filename = line.Split(new char[] {' '}, 9,StringSplitOptions.RemoveEmptyEntries)[8]

      

+3


source


Based on Sasa's Suggestion, the following code can be used to get a list of files.

List<string> availableFiles = new List<string>();
string line = string.Empty;

ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
using (FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse())
{
    using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
    {
        line = streamReader.ReadLine();
        while (!string.IsNullOrEmpty(line))
        {
            if (line[0] != 'd')
            {
                availableFiles.Add(line.Split(new char[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries)[8]);
            }

            line = streamReader.ReadLine();
        }
    }
}

      

0


source







All Articles