C#: что такое эффективный способ проанализировать строку с одним разделителем через ReadLine () TextReader?

C#: что эффективный путь состоит в том, чтобы проанализировать строку с одним разделителем для каждого ReadLine () TextReader?

Моя цель состоит в том, чтобы загрузить список прокси к ListView в два столбца (Proxy|Port), читающий из .txt файла. Как был бы я идти после разделения каждого readline () в прокси и переменные порта с разделителем ":"?

Это - то, что я имею до сих пор,

    public void loadProxies(string FilePath)
    {
        string Proxy; // example/temporary place holders
        int Port; // updated at each readline() loop.

        using (TextReader textReader = new StreamReader(FilePath))
        {
            string Line;
            while ((Line = textReader.ReadLine()) != null)
            {
                // How would I go about directing which string to return whether
                // what's to the left of the delimiter : or to the right?
                //Proxy = Line.Split(':');
                //Port = Line.Split(':');

                // listview stuff done here (this part I'm familiar with already)
            }
        }
    }

В противном случае существует ли более эффективный способ сделать это?

5
задан Cœur 16 March 2019 в 17:36
поделиться

5 ответов

Вы можете попробовать что-то подобное.

var items = File.ReadAllText(FilePath)
    .Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
    .Select(line => line.Split(':'))
    .Select(pieces => new { 
        Proxy = pieces[0], 
        Port = int.Parse(pieces[1]) 
    });

Если вы знаете, что в конце файла не будет случайной новой строки, вы можете это сделать.

var items = File.ReadAllLines(FilePath)
    .Select(line => line.Split(':'))
    .Select(pieces => new { 
        Proxy = pieces[0], 
        Port = Convert.ToInt32(pieces[1]) 
    });
0
ответ дан 14 December 2019 в 08:48
поделиться

Как насчет выполнения регулярного выражения для всего файла?

var parts=
    Regex.Matches(input, @"(?<left>[^:]*):(?<right>.*)",RegexOptions.Multiline)
    .Cast<Match>()
    .Where(m=>m.Success)
    .Select(m => new
        {
            left = m.Groups["left"],
            right = m.Groups["right"]
        });

foreach(var part in parts)
{
    //part.left
    //part.right
}

Или, если он слишком велик, почему бы не выполнить Linqify операцию ReadLine с помощью метода уступки?

static IEnumerable<string> Lines(string filename)
{
    using (var sr = new StreamReader(filename))
    {
        while (!sr.EndOfStream)
        {
            yield return sr.ReadLine();
        }
    }
}

И запустить ее так:

var parts=Lines(filename)
.Select(
    line=>Regex.Match(input, @"(?<left>[^:]*):(?<right>.*)")
)
.Where(m=>m.Success)
.Select(m => new
    {
        left = m.Groups["left"],
        right = m.Groups["right"]
    });
foreach(var part in parts)
{
    //part.left
    //part.right
}
2
ответ дан 14 December 2019 в 08:48
поделиться
string [] parts = line.Split(':');
string proxy = parts[0];
string port = parts[1];
2
ответ дан 14 December 2019 в 08:48
поделиться

You можно разделить их следующим образом:

        string line;
        string[] tokens;
        while ((Line = textReader.ReadLine()) != null)
        {
            tokens = line.Split(':');
            proxy = tokens[0];
            port = tokens[1];

            // listview stuff done here (this part I'm familiar with already)
        }

лучше всего использовать имена переменных в C # с маленькой буквы, так как остальные зарезервированы для имен классов / пространств имен и т. д.

2
ответ дан 14 December 2019 в 08:48
поделиться

С точки зрения эффективности Я думаю, вам будет сложно превзойти:

    int index = line.IndexOf(':');
    if (index < 0) throw new InvalidOperationException();
    Proxy = line.Substring(0, index);
    Port = int.Parse(line.Substring(index + 1));

Это позволяет избежать создания / распределения массива связан с Split , и смотрит только до первого разделителя. Но я должен подчеркнуть, что это вряд ли будет подлинным узким местом в производительности, если объем данных не будет огромным , так что почти любой подход подойдет. На самом деле, возможно, самая важная вещь (мне напомнил комментарий ниже) - это приостановить пользовательский интерфейс при добавлении:

myListView.BeginUpdate();
try {
    // TODO: add all the items here
} finally {
    myListView.EndUpdate();
}
1
ответ дан 14 December 2019 в 08:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: