我有一个应用程序执行以下操作:目录列表,下载文件,全部下载。
我在从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);
答案 0 :(得分:11)
最终解决方案是使用正则表达式并使用组拆分它。这解决了所有问题,并允许我获取文件/目录名称以及它是目录还是文件。
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);
答案 1 :(得分:4)
更简单的解决方案可能是:
isDirectory=line[0]=='d';
filename = line.Split(new char[] {' '}, 9,StringSplitOptions.RemoveEmptyEntries)[8]
答案 2 :(得分:0)
基于Sasa's suggestion,以下代码可用于获取文件列表。
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();
}
}
}