我有一个相当大的文件,大约80MB,并希望将其分成几块。 我的管道分隔文件结构是这样的:
Name|ID|Phone|Address
Al|34|3453453234|123 Main
Bo|456|44545|123 Main
Al|34|455666|5th Ave
James|007|7021023456|Green Ave
但是当你看到一个人的信息可能散布在整个文件中时所以首先LINQ编写了一个文件分类器来按ID对文件的行进行排序,所以我的文件现在看起来像这样:
Name|ID|Phone|Address
James|007|7021023456|Green Ave
Al|34|3453453234|123 Main
Al|34|455666|5th Ave
Bo|456|44545|123 Main
我想说好的让我们把它分成更小的文件,让每个文件最多包含50个人。所以关键的事情,也是我无法弄清楚的主要事情是如何编写代码,确保每个文件最多包含50个人 AND 确保每个人的记录都在相同文件中?
答案 0 :(得分:1)
可能有以下几点:
// Take 50 records
var first50 = source.Take(50).ToList();
// Add all records which have the same name as the last taken record
var additional = source.TakeWhile(p => p.Name == first50.Last().Name);
需要一些角落案件处理(空文件等),但这个想法应该有用。
答案 1 :(得分:1)
也许有一些更简单但这应该有效:
var dataLines = File.ReadLines(@"C:\Temp\SplitFileTest\BigFile.txt")
.SkipWhile(l => String.IsNullOrWhiteSpace(l)).Skip(1); //skip header
var dataIdGroups = dataLines
.Select(l => new { Line = l.Trim(), Fields = l.Trim().Split('|') })
.Where(x => x.Fields.Length == 4)
.Select(x => new
{
Name = x.Fields[0],
ID = x.Fields[1],
Phone = x.Fields[2],
Address = x.Fields[3],
Line = x.Line
})
.GroupBy(x => x.ID);
var allFileLines = new List<List<string>>();
foreach (var userGroup in dataIdGroups)
{
if (userGroup.Count() > 50 || allFileLines.Count == 0 || allFileLines.Last().Count + userGroup.Count() > 50)
allFileLines.Add(userGroup.Select(x => x.Line).ToList());
else
allFileLines.Last().AddRange(userGroup.Select(x => x.Line));
}
for(int i = 0; i < allFileLines.Count; i++)
File.WriteAllLines(
string.Format(@"C:\Temp\SplitFileTest\UserFile_{0}.txt", i + 1),
allFileLines[i]);
我已经使用一些示例数据对其进行了测试,并且它从一个大文件中创建了4个文件,每个用户始终完全在一个文件中。只有当文件包含少于50行并且下一个用户确实适合该文件时,它才会混合。