从 WebRequestMethods.Ftp.ListDirectoryDetails 中提取文件名

7
我有一个应用程序,可以进行以下操作:目录列表、下载文件、下载所有文件。
我遇到了一个问题,就是无法从 WebRequestMethods.Ftp.ListDirectoryDetails 中获取文件名。看起来在每种情况下都不可能这样做。
WebRequestMethods.Ftp.ListDirectoryDetails 以如下方式返回 lineItem:
"-rw-r--r-- 1 ftp ftp 39979 Aug 01 16:02 db to pc 2014-08-05 07-30-00.csv"
我使用第一个字符来确定它是文件还是目录。然后我在空格上分割文件,并在分割后的固定索引量之后获取文件名。我的实现中的问题是,如果一个文件有多个空格,则会使用较少的空格错误地引用它,并且在尝试下载它时找不到该文件。
我不能使用 split.last(),因为文件名可以有空格,也不能使用 WebRequestMethods.Ftp.ListDirectory,因为它不允许我们区分没有扩展名的目录和文件。正则表达式也不行,因为文件名中可能包含日期。任何能够完全覆盖所有情况的解决方案都将是非常好的帮助。
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个回答

14
最终的解决方案是使用正则表达式,并使用分组进行拆分。这解决了所有问题,并允许我获取文件/目录名称以及它是目录还是文件。
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);

感谢:http://blogs.msdn.com/b/adarshk/archive/2004/09/15/sample-code-for-parsing-ftpwebrequest-response-for-listdirectorydetails.aspx提供正则表达式。


我无法使用WebRequestMethods.Ftp.ListDirectoryDetails获取权限详细信息。我需要提供权限才能获取文件/文件夹的权限详细信息吗?请帮忙解决。 - Vijay

5
更简单的解决方案可以是:
isDirectory=line[0]=='d'; 
filename = line.Split(new char[] {' '}, 9,StringSplitOptions.RemoveEmptyEntries)[8]

这太棒了。简短明了。谢谢你。 - Marty_in_a_Box

0

根据Sasa的建议,可以使用以下代码获取文件列表。

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();
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接