如何将FTP.ListDirectoryDe​​tails的响应映射到对象

时间:2016-08-31 14:19:12

标签: c# ftp ftpwebrequest

FTP.ListDirectoryDe​​tails的输出通常是一个类似于下面给出的字符串:

  

-rw-r - r-- 1 ftp ftp 960 Aug 31 09:09 test1.xml

如何将其转换为易于使用的对象?

1 个答案:

答案 0 :(得分:1)

我无法找到将其转换为有用对象的合适解决方案,因此我创建了自己的对象。我希望下面的代码可以帮助别人。如果您有改进此代码的建议,请随时提供。

这是班级:

/// <summary>
/// This class represents the file/directory information received via FTP.ListDirectoryDetails
/// </summary>
public class ListDirectoryDetailsOutput
{
    public bool IsDirectory { get; set; }
    public bool IsFile {
        get { return !IsDirectory; } 
    }

    //Owner permissions
    public bool OwnerRead { get; set; }
    public bool OwnerWrite { get; set; }
    public bool OwnerExecute { get; set; }

    //Group permissions
    public bool GroupRead { get; set; }
    public bool GroupWrite { get; set; }
    public bool GroupExecute { get; set; }

    //Other permissions
    public bool OtherRead { get; set; }
    public bool OtherWrite { get; set; }
    public bool OtherExecute { get; set; }

    public int NumberOfLinks { get; set; }
    public int Size { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string Name { get; set; }

    public bool ParsingError { get; set; }
    public Exception ParsingException { get; set; }

    /// <summary>
    /// Parses the FTP response for ListDirectoryDetails into the Output object
    /// An example input of a file called test1.xml:
    /// -rw-r--r-- 1 ftp ftp            960 Aug 31 09:09 test1.xml
    /// </summary>
    /// <param name="ftpResponseLine"></param>
    public ListDirectoryDetailsOutput(string ftpResponseLine)
    {
        try
        {
            string[] responseList = ftpResponseLine.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

            string permissions = responseList[0];
            //Get directory, currently only checking for not "-", might be beneficial to also check for "d" when mapping IsDirectory
            IsDirectory = !string.Equals(permissions.ElementAt(0), '-');

            //Get directory, currently only checking for not "-", might be beneficial to also check for r,w,x when mapping permissions
            //Get Owner Permissions
            OwnerRead = !string.Equals(permissions.ElementAt(1), '-');
            OwnerWrite = !string.Equals(permissions.ElementAt(2), '-');
            OwnerExecute = !string.Equals(permissions.ElementAt(3), '-');

            //Get Group Permissions
            GroupRead = !string.Equals(permissions.ElementAt(4), '-');
            GroupWrite = !string.Equals(permissions.ElementAt(5), '-');
            GroupExecute = !string.Equals(permissions.ElementAt(6), '-');

            //Get Other Permissions
            OtherRead = !string.Equals(permissions.ElementAt(7), '-');
            OtherWrite = !string.Equals(permissions.ElementAt(8), '-');
            OtherExecute = !string.Equals(permissions.ElementAt(9), '-');

            NumberOfLinks = int.Parse(responseList[1]);

            Size = int.Parse(responseList[4]);
            string dateStr = responseList[5] + " " + responseList[6] + " " + responseList[7];
            //Setting Year to the current year, can be changed if needed
            dateStr += " " + DateTime.Now.Year.ToString();

            ModifiedDate = DateTime.ParseExact(dateStr, "MMM dd hh:mm yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces);

            Name = (responseList[8]);
            ParsingError = false;
        }
        catch (Exception ex)
        {
            ParsingException = ex;
            ParsingError = true;
        }
    }
}

以下是我如何使用它:

            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(FTPURL);
            request.Credentials = new NetworkCredential(FTPUsername, FTPPassword);
            //Only required for SFTP
            //request.EnableSsl = true;
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            StreamReader streamReader = new StreamReader(response.GetResponseStream());

            List<ListDirectoryDetailsOutput> directories = new List<ListDirectoryDetailsOutput>();

            string line = streamReader.ReadLine();
            while (!string.IsNullOrEmpty(line))
            {
                directories.Add(new ListDirectoryDetailsOutput(line));
                line = streamReader.ReadLine();
            }

            streamReader.Close();

请注意:这仅在输入字符串完全采用相同格式时才有效。如果不是,ParsingError将为true,异常将被捕获为ParsingException。

注2:1年以前的文件格式为MMM dd yyyy,而不是MMM dd hh:mm。这将需要在上面的代码中进行一些调整。缺少年份并不总是意味着当前年份(给出的代码假设不正确)。缺少一年只意味着去年。当在4月份收到12月20日的文件时,错过的一年将意味着去年,而不是今年。 (谢谢马丁!)