c# - 将大列表拆分为较小的子列表
c# - splitting a large list into smaller sublists
刚接触 C# - 坐在这里练习。我有一个文件,其中列出了 1000 万个密码,我下载了一个文件来练习。
我想将文件分解为 99 个列表。在 99 处停止然后做一些事情。然后从它停止的地方开始,对下一个 99 重复执行某些操作,直到到达文件中的最后一项。
我可以很好地完成计数部分,它是在 99 处停止并从我停止的地方继续是我遇到问题的地方。我在网上找到的任何东西都与我想要做的不相近,我自己添加到此代码中的任何东西都不起作用。
如果我不清楚,我很乐意分享更多信息。随便问一下,我会回复的,但是我可能要到明天才能回复,具体取决于现在的时间。
这是我开始的代码:
using System;
using System.IO;
namespace lists01
{
class Program
{
static void Main(string[] args)
{
int count = 0;
var f1 = @"c:\tmp-million-password-list-top-1000000.txt";
{
var content = File.ReadAllLines(f1);
foreach (var v2 in content)
{
count++;
Console.WriteLine(v2 + "\t" + count);
}
}
}
}
}
我的最终目标是对我拥有的文件中的任何项目列表执行此操作。我只使用这个密码列表是因为它相当大,而且我认为它对这个练习有好处。
谢谢
基思
这里有几种不同的方法来解决这个问题。通常,我会建议您在代码中使用 ReadAllLines
函数。权衡是您一次将整个文件加载到内存中,然后对其进行操作。
使用与 Linq 的 Skip()
和 Take()
方法一致的读取所有行,您可以将行分成这样的组:
var lines = File.ReadAllLines(fileName);
int linesAtATime = 99;
for (int i = 0; i < lines.Length; i = i + linesAtATime)
{
List<string> currentLinesGroup = lines.Skip(i).Take(linesAtATime).ToList();
DoSomethingWithLines(currentLinesGroup);
}
但是,如果您正在处理一个非常大的文件,将整个文件加载到内存中可能不切实际。另外,您可能不想在处理线条时让文件保持打开状态。此选项使您可以更好地控制文件的移动方式。它只是将需要的部分加载到内存中,并在您处理当前行集时关闭文件。
List<string> lines = new List<string>();
int maxLines = 99;
long seekPosition = 0;
bool fileLoaded = false;
string line;
while (!fileLoaded)
{
using (Stream stream = File.Open(fileName, FileMode.Open))
{
//Jump back to the previous position
stream.Seek(seekPosition, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream && lines.Count < maxLines)
{
line = reader.ReadLine();
seekPosition += (line.Length + 2); //Tracks how much data has been read.
lines.Add(line);
}
fileLoaded = reader.EndOfStream;
}
}
DoSomethingWithLines(lines);
lines.Clear();
}
在本例中,我使用了Stream
,因为它能够查找到文件中的特定位置。但是后来我使用了 StreaReader
因为它有 ReadLine()
方法。
刚接触 C# - 坐在这里练习。我有一个文件,其中列出了 1000 万个密码,我下载了一个文件来练习。
我想将文件分解为 99 个列表。在 99 处停止然后做一些事情。然后从它停止的地方开始,对下一个 99 重复执行某些操作,直到到达文件中的最后一项。
我可以很好地完成计数部分,它是在 99 处停止并从我停止的地方继续是我遇到问题的地方。我在网上找到的任何东西都与我想要做的不相近,我自己添加到此代码中的任何东西都不起作用。
如果我不清楚,我很乐意分享更多信息。随便问一下,我会回复的,但是我可能要到明天才能回复,具体取决于现在的时间。
这是我开始的代码:
using System;
using System.IO;
namespace lists01
{
class Program
{
static void Main(string[] args)
{
int count = 0;
var f1 = @"c:\tmp-million-password-list-top-1000000.txt";
{
var content = File.ReadAllLines(f1);
foreach (var v2 in content)
{
count++;
Console.WriteLine(v2 + "\t" + count);
}
}
}
}
}
我的最终目标是对我拥有的文件中的任何项目列表执行此操作。我只使用这个密码列表是因为它相当大,而且我认为它对这个练习有好处。
谢谢 基思
这里有几种不同的方法来解决这个问题。通常,我会建议您在代码中使用 ReadAllLines
函数。权衡是您一次将整个文件加载到内存中,然后对其进行操作。
使用与 Linq 的 Skip()
和 Take()
方法一致的读取所有行,您可以将行分成这样的组:
var lines = File.ReadAllLines(fileName);
int linesAtATime = 99;
for (int i = 0; i < lines.Length; i = i + linesAtATime)
{
List<string> currentLinesGroup = lines.Skip(i).Take(linesAtATime).ToList();
DoSomethingWithLines(currentLinesGroup);
}
但是,如果您正在处理一个非常大的文件,将整个文件加载到内存中可能不切实际。另外,您可能不想在处理线条时让文件保持打开状态。此选项使您可以更好地控制文件的移动方式。它只是将需要的部分加载到内存中,并在您处理当前行集时关闭文件。
List<string> lines = new List<string>();
int maxLines = 99;
long seekPosition = 0;
bool fileLoaded = false;
string line;
while (!fileLoaded)
{
using (Stream stream = File.Open(fileName, FileMode.Open))
{
//Jump back to the previous position
stream.Seek(seekPosition, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream && lines.Count < maxLines)
{
line = reader.ReadLine();
seekPosition += (line.Length + 2); //Tracks how much data has been read.
lines.Add(line);
}
fileLoaded = reader.EndOfStream;
}
}
DoSomethingWithLines(lines);
lines.Clear();
}
在本例中,我使用了Stream
,因为它能够查找到文件中的特定位置。但是后来我使用了 StreaReader
因为它有 ReadLine()
方法。