尝试在一组文件中获取不同标识符的集合。我对这个Lambda查询做错了什么:
var enumDir = Directory.GetFiles(folder);
var distinctCode = enumDir.Select(s => Path.GetFileName(s).Substring(8, 4))
.GroupBy(s => s.ToString());
提前致谢...
@empi建议。我希望从文件名中得到一个不同的4个字母子字符串的列表,我得到的是什么,或者我首先将Path.Get ....部分放入组中,并且我得到了一个超出范围的索引异常。
@Oskar Kjellin建议我应该提到每个文件名的长度都是45个字符
var enumDir = Directory.GetFiles(folder).Where(a => Path.GetFileName(a).Length > 12);
var distinctCode = enumDir.Select(s => Path.GetFileName(s).Substring(8, 4)).Distinct();
真的是两种建议的组合,我不知道是谁真正标记答案。
答案 0 :(得分:1)
在调用子字符串之前,您应该始终检查长度以避免异常......
enumDir = Directory.GetFiles(folder);
distinctCode = enumDir.Select(s => Path.GetFileName(s))
.Select( s=> s.Length >= 12 ? s.Substring(8, 4) : s).GroupBy(s => s);
您永远无法真正控制文件夹中的文件。例如,windows可以创建thumbs.db,它是图像或其他临时文件缩略图的缓存。
也许您只想过滤掉那些固定长度的人:
enumDir = Directory.GetFiles(folder);
distinctCode = enumDir.Select(s => Path.GetFileName(s)).Where(s=>s.Length == 45)
.Select( s=> s.Substring(8, 4)).GroupBy(s => s);
答案 1 :(得分:1)
enumDir.Select(s => Path.GetFileName(s).Substring(8, 4))
- 此代码应返回IEnumerable<string>
- 检查此集合是否正常。如果没问题,那么只需使用Distinct()
。
答案 2 :(得分:1)
我怀疑你要找的是获取实际的文件名,但是用子串将它们分组。
var result = Directory.GetFiles(folder)
.Select(s => Path.GetFileName(s))
.Where(s => s.Length > 12)
.GroupBy(s => s.Substring(8, 4));
现在在result
中,您拥有Key
作为子字符串的组对象,如果您枚举它们,则会获得与该键匹配的实际文件名。
答案 3 :(得分:1)
我认为使用正则表达式进行验证可以做得更好。您在查询中尝试执行的检查类型太复杂,无法在单个查询中执行。可能在该目录中可能存在其他文件,这些文件不符合您期望的模式,并且可能会弄乱所有内容。这种复杂性可以通过正则表达式来捕获。如果您的文件名遵循某种模式,那么简单的正则表达式匹配就可以为您处理。
我不知道你的文件名是怎么样的,所以我将以Windows Media Center的录制电视为例。所有WMC文件名都有一定的模式:
[title]_[station]_[year]_[month]_[day]_[hour]_[minute]_[second].wtv
然后按标题对所有视频进行分组,您可以这样做:
var dir = @"C:\Users\Public\Recorded TV";
var wmcFileRe = new Regex(@"
^
(?<title>.+)
_
(?<station>.+)
_
(?<date>\d{4}_\d{2}_\d{2})
_
(?<time>\d{2}_\d{2}_\d{2})
\.wtv
$
", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
var query =
from filePath in Directory.EnumerateFiles(dir)
let fileName = Path.GetFileName(filePath)
let match = wmcFileRe.Match(fileName)
where match.Success
orderby match.Groups["title"].Value,
match.Groups["date"].Value descending,
match.Groups["time"].Value descending
group filePath by match.Groups["title"].Value;
产生类似这样的东西:
另外,请使用Directory.EnumerateFiles()
代替Directory.GetFiles()
,这样您就不会预先创建该数组结果,而在其他任何地方都不需要该数组。