Лучший способ записать огромную строку в файл - PullRequest
12 голосов
/ 17 февраля 2011

В C # я читаю файл среднего размера (100 КБ ~ 1 МБ), изменяю некоторые части содержимого и, наконец, пишу в другой файл.Все содержимое текстовое.Модификация выполняется как строковые объекты и строковые операции.Мой текущий подход:

  1. Считайте каждую строку из исходного файла, используя StreamReader.
  2. Откройте StringBuilder для содержимого нового файла.
  3. Изменить строковый объект и вызвать AppendLine из StringBuilder (до конца файла)
  4. Открыть новый StreamWriter и записать StringBuilder в поток записи.

Однако я обнаружил, что StremWriter.Write усекает 32768 байт (2 ^ 16), но длина StringBuilder больше этой.Я мог бы написать простой цикл, чтобы гарантировать всю строку в файл.Но мне интересно, что было бы наиболее эффективным способом в C # для выполнения этой задачи?

Подводя итог, я хотел бы изменить только некоторые части текстового файла и записать в другой файл.Но размер текстового файла может быть больше 32768 байт.

== Ответ == Извините, что запутал вас!Просто я не позвонил flush.StremWriter.Write не имеет короткого (например, 2 ^ 16) ограничения.

Ответы [ 7 ]

11 голосов
/ 17 февраля 2011

StreamWriter.Write

не

усекает строку и не имеет ограничений.

Внутренне она использует String.CopyTo, а с другой стороны использует небезопаснокод (используя fixed) для копирования символов, чтобы он был наиболее эффективным .

4 голосов
/ 17 февраля 2011

Проблема, скорее всего, связана с не закрытием писателя. Смотри http://msdn.microsoft.com/en-us/library/system.io.streamwriter.flush.aspx.

Но я бы предложил не загружать весь файл в память, если этого можно избежать.

1 голос
/ 17 февраля 2011

Вы можете попробовать это:

    void Test()
    {
        using (var inputFile = File.OpenText(@"c:\in.txt"))
        {
            using (var outputFile = File.CreateText(@"c:\out.txt"))
            {
                string current;
                while ((current = inputFile.ReadLine()) != null)
                {
                    outputFile.WriteLine(Process(current));
                }
            }
        }
    }

    string Process(string current)
    {
        return current.ToLower();
    }

Во избежание необходимости загружать полный файл в память, обрабатывая строку за строкой и записывая его напрямую

0 голосов
/ 17 февраля 2011

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

using (StreamReader sr = new StreamReader(@"test.txt"))
{
    using (StreamWriter sw = new StreamWriter(@"modifiedtest.txt"))
    {
        while (!sr.EndOfStream)
        {
            string line = sr.ReadLine();
            //do some modifications
            sw.WriteLine(line);
            sw.Flush(); //force line to be written to disk
        }
    }
}
0 голосов
/ 17 февраля 2011

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

0 голосов
/ 17 февраля 2011

Вместо того, чтобы работать через дырочный документ, я бы использовал регулярное выражение, чтобы найти то, что вы ищете Пример:

public List<string> GetAllProfiles()
    {
        List<string> profileNames = new List<string>();
        using (StreamReader reader = new StreamReader(_folderLocation + "profiles.pg"))
        {
            string profiles = reader.ReadToEnd();
            var regex = new Regex("\nname=([^\r]{0,})", RegexOptions.IgnoreCase);
            var regexMatchs = regex.Matches(profiles);
            profileNames.AddRange(from Match regexMatch in regexMatchs select regexMatch.Groups[1].Value);
        }
        return profileNames;
    }
0 голосов
/ 17 февраля 2011

Вы пробовали File.WriteAllText() метод?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...