我想从文件列表中选择只有这么多文件,它们的总大小不超过阈值(即目标驱动器上的可用空间量).
我知道我可以通过在循环中添加文件大小来实现此目的,直到达到阈值,然后使用该数字从列表中选择文件.但是,是否可以使用LINQ查询来实现?
这可能有效(files是List<FileInfo>):
var availableSpace = DriveInfo.GetDrives()
.First(d => d.Name == @"C:\").AvailableFreeSpace;
long usedSpace = 0;
var availableFiles = files
.TakeWhile(f => (usedSpace += f.Length) < availableSpace);
foreach (FileInfo file in availableFiles)
{
Console.WriteLine(file.Name);
}
Run Code Online (Sandbox Code Playgroud)
你可以通过使用一个闭包来实现:
var directory = new DirectoryInfo(@"c:\temp");
var files = directory .GetFiles();
long maxTotalSize = 2000000;
long aggregatedSize = 0;
var result = files.TakeWhile(fileInfo =>
{
aggregatedSize += fileInfo.Length;
return aggregatedSize <= maxTotalSize;
});
Run Code Online (Sandbox Code Playgroud)
但有一点需要注意,因为aggregatedSize在您离开已定义的范围后,变量可能会被修改.
你可以在扩展方法中包装它 - 这将消除闭包:
public static IEnumerable<FileInfo> GetWithMaxAggregatedSize(this IEnumerable<FileInfo> files, long maxTotalSize)
{
long aggregatedSize = 0;
return files.TakeWhile(fileInfo =>
{
aggregatedSize += fileInfo.Length;
return aggregatedSize <= maxTotalSize;
});
}
Run Code Online (Sandbox Code Playgroud)
你最终使用这样的方法:
var directory = new DirectoryInfo(@"c:\temp");
var files = directory.GetFiles().GetWithMaxAggregatedSize(2000000);
Run Code Online (Sandbox Code Playgroud)
编辑:我用Where-method 取代了TakeWhile-method.TakeWhile一旦达到阈值,-extension将停止,而Where-extension将继续.培养TakeWhileTim-Schteter的积分可以归功于Tim Schmelter.