WPF C#: Разделение длинной строки

#c# #string #split

Вопрос:

Я долго думал об этой проблеме, но теперь мне удалось обратиться за помощью к тем, кто знает. У меня есть код, который должен считывать текст из большого файла (несколько Gbs) строка за строкой. Каждая строка может быть около 500 Мб, так как это должно быть видео, преобразованное в base64, связанное с именем видео. Здесь я читаю текущую строку и отделяю название видео от его содержимого (начните с другого).

         string[] fileline = GetFileLine(resPath, currentRow).Split(); //Here split causes SystemOutOfMemory
        try
        {
            string base64 = fileline[0].Replace(specSymbol, ' ');
            try
            {
                if (!IsVideo(ref base64) amp;amp; !IsGif(ref base64))
                {
                    ShowPrimary();
                    imgFile.Source = BytesToBitmap(Convert.FromBase64String(base64));
                }
                else
                    btnLoadFile.Background = readyColor;
                if (fileline.Length > 1)
                    return fileline[1].Replace(specSymbol, ' ');
            }
            catch (Exception ex3) { MessageBox.Show("Next(4):"   ex3.Message); }
        }
        catch (Exception ex2) { MessageBox.Show("Next(3):"   ex2.Message); }
 

Поэтому мой вопрос таков: существует ли способ разделения длинных строк, или мне нужно только хранить имена в отдельном файле без разделения?

ОБНОВЛЕНИЕ 1: Я написал метод, используя совет, который дал мне @canton7. Я протестировал его на действительно небольших файлах (около 100 символов), где он хорошо работает, но сейчас я тестирую его на файле размером 25 МБ, и скорость чтения ужасна (например, 10 МБ в час), хотя чтение действительно больших файлов не привело к сбою программы, поэтому я думаю, что я на правильном пути. Я все еще задаюсь вопросом, есть ли лучший метод. Если у вас есть какие — то советы по улучшению готового метода- пожалуйста, дайте их здесь.

 static string ReadFirstHalfAfter(string path, int skips = 0)
{
    int skipsDone = 0;
    int ri = 0;
    char[] buffer = new char[1];
    StreamReader reader = new StreamReader(path);
    while (reader.Peek() >= 0)//while reader is not at the end of file
    {
        reader.Read(buffer, ri, 1);//reading one element from the current position
        if (skipsDone < skips)//line skips not enough
        {
            if (buffer[buffer.Length - 1] == 'n')//current symbol is line end 
            { 
                skipsDone  ;//line skip counted
                continue;
            }
        }
        else//enough line skips
        {
            if (buffer[buffer.Length - 1] == ' ') break; //if line separator - stop
            ExpandArray(ref buffer); //adding one more free element
            ri  ; //switching element to read next
        }
        if (ri % 10000 == 0) Console.Write('.');
    }
    return new string(buffer).Trim(' ');
}
 

Комментарии:

1. Почему бы не использовать потоковый считыватель? Таким образом, вы можете читать каждую строку по символам: сначала имя файла (продолжайте читать символы, пока не найдете пробелы), а затем вы можете читать отдельные символы и передавать их через форму frombase64 и записывать каждый полученный байт непосредственно в другой файл (или локальную переменную).

2. @canton7 Спасибо за совет, я попробую завтра.

3. Возможно, стоит немного подправить этот вопрос, чтобы он был более кратким — это хорошая тема, но есть много лишних вопросов, которые отвлекают от основного вопроса «Как разделить длинную строку в C# без нехватки памяти».

4. «Максимальный размер строкового объекта в памяти составляет 2 ГБ, или около 1 миллиарда символов». вы устали использовать подстроку и индекс? Я бы не предложил читать по 1 символу за раз для файла такого размера, но это IMHO.

5. @Sorceri Это идея, но я не уверен, что она будет более оптимизирована, чем просто разделение с точки зрения памяти. В любом случае, я попробую и дам вам знать, спасибо.

Ответ №1:

Чтобы разделить строку на 2 части, вы можете использовать подстроку для экономии памяти, но если вы хотите сохранить больше памяти — есть только один способ записи частей строки в разных строках.