首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# & LINQ;将文件分组为5MB组

C# & LINQ;将文件分组为5MB组
EN

Stack Overflow用户
提问于 2010-12-31 01:03:01
回答 4查看 1.1K关注 0票数 3

问候,我正在尝试编写一个Linq查询来在文件名列表上运行,该查询返回分组为5MB块的文件列表。因此,每个组都将包含一个文件名列表,这些文件名总/合计MB最大为5MB。

我对Linq没意见,但这一次我不知道从哪里开始。帮助

代码语言:javascript
复制
DirectoryInfo di = new DirectoryInfo (@"x:\logs");
List<string> FileList = di.GetFiles ("*.xml")
var Grouped = FileList =>
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-31 01:15:01

是的,你可以用LINQ做到这一点。

代码语言:javascript
复制
var groupedFiles = files.Aggregate(
    new List<List<FileInfo>>(),
    (groups, file) => {
        List<FileInfo> group = groups.FirstOrDefault(
           g => g.Sum(f => f.Length) + file.Length <= 1024 * 1024 * 5
        );
        if (group == null) {
            group = new List<FileInfo>();
            groups.Add(group);
        }
        group.Add(file);
        return groups;
    }
);

这个算法是贪婪的。它只会找到第一个列表,它可以将FileInfo推入其中,而不会超过5MB的上限。就最小化组的数量而言,它并不是最优的,但您没有将其作为约束来说明。我认为在调用Aggregate之前使用OrderBy(f => f.Length)会有所帮助,但我现在真的没有时间深入考虑这一点。

票数 1
EN

Stack Overflow用户

发布于 2010-12-31 01:21:35

首先看一下this StackOverflow question。它解决了分组到子列表中的问题。然后,诀窍是检测group by子句中的文件大小。这可能是一个不使用LINQ可能比使用LINQ更清楚的答案。

部分问题是您有一个文件名列表。您需要File对象的列表,以便可以通过LINQ查询文件的大小。在Linq4.0中,你有一个应该是你想要的group-by-into结构。

票数 0
EN

Stack Overflow用户

发布于 2010-12-31 01:25:15

这里有一种方法:

  1. 定义一种类型,该类型接受文件大小作为输入,并返回一个值,该值随着达到指定的最大值而递增并重置。(此类型负责维护其自身的状态。)
  2. 按此类型返回的值进行分组。

代码示例:

代码语言:javascript
复制
// No idea what a better name for this would be...
class MaxAmountGrouper
{
    readonly int _max;

    int _id;
    int _current;

    public MaxAmountGrouper(int max)
    {
        _max = max;
    }

    public int GetGroupId(int amount)
    {
        _current += amount;
        if (_current >= _max)
        {
            _current = 0;
            return _id++;
        }

        return _id;
    }
}

用法:

代码语言:javascript
复制
const int BytesPerMb = 1024 * 1024;

DirectoryInfo directory = new DirectoryInfo(@"x:\logs");
FileInfo[] files = directory.GetFiles("*.xml");

var grouper = new MaxAmountGrouper(5 * BytesPerMb);
var groups = files.GroupBy(f => grouper.GetGroupId((int)f.Length));

foreach (var g in groups)
{
    long totalSize = g.Sum(f => f.Length);
    Console.WriteLine("Group {0}: {1} MB", g.Key, totalSize / BytesPerMb);
    foreach (FileInfo f in g)
    {
        Console.WriteLine("File: {0} ({1} MB)", f.Name, f.Length / BytesPerMb);
    }
    Console.WriteLine();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4564582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档