如何映射FTP的响应?ListDirectoryDetails到一个对象

本文关键字:响应 ListDirectoryDetails 一个对象 FTP 何映射 映射 | 更新日期: 2023-09-27 18:05:11

FTP的输出。ListDirectoryDetails通常是一个类似于下面给出的字符串:

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

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

如何映射FTP的响应?ListDirectoryDetails到一个对象

我找不到一个合适的解决方案来将它转换成一个有用的对象,所以我创建了我自己的。我希望下面的代码对其他人有所帮助。如果您有改进此代码的建议,请随时贡献。

下面是类:

/// <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日的文件,那么遗漏的年份意味着去年,而不是今年。(谢谢马丁!)