c# - разбиение большого списка на меньшие. - PullRequest
0 голосов
/ 19 января 2020

Довольно плохо знаком с C# - Сидеть здесь, тренируясь. У меня есть файл с 10 миллионами паролей, перечисленных в одном файле, который я скачал для практики.

Я хочу разбить файл на списки 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\10-million-password-list-top-1000000.txt";           
        {                
            var content = File.ReadAllLines(f1);
            foreach (var v2 in content)
            {
                count++;
                Console.WriteLine(v2 + "\t" + count);
            }
        }
    }
}
}

Моя конечная цель - сделать это с любым списком элементов из файлов, которые у меня есть. Я использую только этот список паролей, потому что он был значительным и думал, что это будет хорошо для этого упражнения.

Спасибо, Кит

1 Ответ

0 голосов
/ 19 января 2020

Вот несколько разных подходов к этому. Обычно я бы предложил функцию ReadAllLines, которая есть в вашем коде. Компромисс в том, что вы загружаете весь файл в память сразу, а затем работаете с ним.

Используя чтение всех строк совместно с Skip() и Take() методами Linq, вы можете разбить строки на группы следующим образом:

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, потому что он имеет возможность искать определенную позицию c в файле. Но тогда я использовал StreaReader, потому что у него есть методы ReadLine().

...