让我们说我有一个很大的字符串列表,称为“ lines”,它包含文本文件中的所有行(通常是大约100k-100万行的大数字)
List<string> lines = File.ReadAllLines("Lines.txt");
我的问题是我需要根据用户输入的块大小来分割文件(或列表)。假设我们有1万行
Lines.txt
,用户输入4400行的大块
File1 = 4400 Lines
File2 = 4400 Lines
File3 = 1200 Lines
我尝试使用我的同事推荐的类似方法,但是我不明白,它不起作用。
public static class ListExtensions
{
public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
}
对于我如何解决此问题的任何建议或帮助,我将不胜感激。
答案 0 :(得分:1)
这个怎么样-
var numOfChunks = lines.Count / chunkSize; // initial number of chunks
if(lines.Count % chunkSize > 0) { numOfChunks++; } // add one chunk for remainder if there is a remainder
for (var i = 0; i <= numOfChunks; i++)
{
var chunk = lines.Skip(i * chunkSize).Take(chunkSize);
// Do something with chunk, like writing to file
}
答案 1 :(得分:0)
Linq的Take
和Skip
在这里可能会有所帮助。
public static List<List<T>> ChunkBy<T>(this List<T> source, int chunkSize)
{
var pages = new List<List<T>>();
var page = 0;
while(source.Any()) {
var l = source.Skip(page++*chunkSize).Take(chunkSize).ToList();
if(!l.Any()) break;
pages.Add(l);
}
return pages;
}
答案 2 :(得分:0)
这里是没有Linq的版本。
public static List<List<T>> ChunkBy<T>(List<T> source, int chunkSize)
{
var pages = new List<List<T>>();
var page = new List<T>();
var i = 0;
foreach( var s in source ) {
if((i++ % chunkSize) == 0 ) { page = new List<T>(); pages.Add(page);}
page.Add(s);
}
return pages;
}
答案 3 :(得分:0)
这是可用于此任务的一种方法。您需要确保传递要分块的sourceFile
文件,将文件写入的destDirectory
和块大小。
private static void ChunkFile(string sourceFile, string destDirectory, int chunkSize)
{
// Read all lines
var lines = File.ReadLines(sourceFile)
// Calculate number of chunks needed
// Round up to get correct chunks
var numberOfChunks = (int)Math.Ceiling((double)lines.Count() / chunkSize);
// Go through each chunk and write to file
for (var i = 0; i < numberOfChunks; i++)
{
// Skip lines chunks we've already seen, and take the next chunk
var chunk = lines.Skip(i * chunkSize).Take(chunkSize);
// Write chunk to destination path
File.WriteAllLines(Path.Combine(destDirectory, $"File{i + 1}.txt"), chunk);
}
}
应该以File1.txt,File2.txt,File3.txt等格式生成分块文件。
您还需要实施错误处理,例如检查sourceFile
是否存在等。
另外,我建议从System.Linq
看一下这两种LINQ方法:
Enumerable.Skip<TSource>(IEnumerable<TSource>, Int32)
Enumerable.Take<TSource>(IEnumerable<TSource>, Int32)
从System.IO
看这些IO方法来读取/写入文件也可能会有所帮助:
注意:我们使用File.ReadLines
而非File.ReadAllLines
来避免将整个文件读入内存。当读取大文件并降低性能时,这是必需的。您可以在What is the difference between File.ReadLines() and File.ReadAllLines()?上了解有关此内容的更多信息。