根据运行总计选择条目

时间:2013-10-18 12:20:22

标签: c# linq

我想从文件列表中选择那么多文件,它们的总大小不超过阈值(即目标驱动器上的可用空间量)。

我知道我可以通过在循环中添加文件大小来实现此目的,直到达到阈值,然后使用该数字从列表中选择文件。但是,是否可以使用LINQ查询来实现?

2 个答案:

答案 0 :(得分:8)

这可行(filesList<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);
}

答案 1 :(得分:5)

您可以通过使用闭包来实现:

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

但有一点需要注意,因为在您将范围放置到已定义范围之后,变量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;
    });
}

你最终使用这样的方法:

var directory = new DirectoryInfo(@"c:\temp");
var files = directory.GetFiles().GetWithMaxAggregatedSize(2000000);

编辑:我用Where - 方法替换了TakeWhile - 方法。 TakeWhile - 扩展程序将在达到阈值后停止,而Where - 扩展程序将继续。提出TakeWhile - 延期的积分将归Tim Schmelter所有。