StringBuilder против StringWriter / StringReader - PullRequest
30 голосов
/ 03 августа 2010

Я недавно читал, что в StringWriter и StringReader используются для записи и чтения из StringBuilder.

Хорошо, когда я использую StringBuilder Object, он выглядит как самодостаточный класс.

У нас есть все возможности для чтения и записи StringBuilder, используя StringBuilder.Append(), Insert(), Replace(), Remove() и т. Д. *

  1. Что такоевозможное использование StringWriter и StringReader, которое не может быть сделано самим StringBuilder?
  2. Каково их практическое применение?
  3. Какова возможная причина, по которой онине принимает Stream в качестве входных данных (потому что любой другой писатель и читатель принимает поток в качестве параметра Конструктора для работы), но StringBuilder?

Ответы [ 4 ]

33 голосов
/ 03 августа 2010

Какое возможное использование StringWriter и StringReader, что не может быть сделано самим StringBuilder?

StringReader и StringWriter происходят от TextReader и TextWriter соответственно,То, что они могут сделать, действует как экземпляр TextReader или TextWriter, который string или StringBuilder не может, потому что они не получают ни один из этих типов.

Каково практическое использованиеиз них?

Они позволяют вам вызывать API, которые ожидают TextReader или TextWriter, когда то, что вы имеете / хотите, является string или StringBuilder.

В чем может быть причина того, что они не принимают Stream в качестве входных данных (потому что любой другой модуль записи и чтения принимает поток в качестве параметра Constructor для работы), кроме StringBuilder?

Потому что они не работают на потоках;они работают на string с или StringBuilder с.Это просто классы-обёртки, которые адаптируют эти типы для API, ожидающих другого интерфейса.См .: рисунок адаптера .

5 голосов
/ 30 ноября 2010

Другие уже сказали, но это потому, что они являются производными от TextReader / TextWriter и могут использоваться вместо них. С одной стороны, имеет смысл использовать тот же метод для вывода строк, который вы используете для файла, если вы хотите, чтобы содержимое было только строкой. Если вам нужен вывод, который будет занимать несколько строк в памяти, зачем беспокоиться о том, что нужно ставить «\ r \ n» в конце каждой строки с помощью StringBuilder? Что делать, если вы хотите, чтобы код запускался или форматировал данные для системы, которая использует только \ n для разрывов строк?

StringBuilder sb = new StringBuilder();
// will be invalid on systems that only use \n
sb.AppendFormat("{0:yyyy-MM-dd HH:mm:ss} - Start\r\n", DateTime.Now);
// still have to add an extra parameter
sb.AppendFormat("The current time is {0:yyyy-MM-dd HH:mm:ss}{1}", DateTime.Now,
    Environment.NewLine);

StringWriter sw = new StringWriter();
// Don't have to worry about it, method name tells you there's a line break
sw.WriteLine("{0:yyyy-MM-dd HH:mm:ss} - Start", DateTime.Now);
// no extra parameters
sw.WriteLine("The current time is {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now);

Скажем, вы хотите обрабатывать файл построчно, возможно, вы бы использовали StreamReader вместо загрузки всего файла в StringBuilder и разделения его на символы новой строки в массиве, верно? С помощью StringReader вы можете использовать точно такой же метод (если он требует универсального TextReader), создав StringReader из строки из TextBox или веб-формы.

Linq2Sql DataContexts имеет свойство Log, которое вы можете установить для TextWriter, чтобы ваши запросы выводились до того, как они будут выполнены, чтобы точно увидеть, что выполняется. Вы можете установить это для TextWriter, прикрепленного к файлу, но вы можете прикрепить к нему StringWriter и выводить содержимое внизу веб-страницы при тестировании ...

1 голос
/ 08 сентября 2014

Вы можете использовать StringReader для чтения всех целых чисел из строки.

private static void Main()
{
    var str = @"
                13
                13
                0 6
                0 5
                0 1
                0 2
                5 3
                6 4
                5 4
                3 4
                7 8
                9 10
                11 12
                9 11
                9 12";


    using (StandardInput input = new StandardInput(new StringReader(str)))
    {
        List<int> integers = new List<int>();
        int n;
        while ((n = input.ReadInt32()) != -1)
        {
            integers.Add(n);
        }
    }
}

Стандартный класс ввода:

class StandardInput : IDisposable
{
    private readonly TextReader reader;

    public StandardInput(TextReader reader)
    {
        this.reader = reader;
    }

    public int ReadInt32()
    {
        while (!char.IsDigit((char)reader.Peek()) && reader.Peek() != -1)
        {
            reader.Read();
        }
        var builder = new StringBuilder();
        while (char.IsDigit((char) reader.Peek()))
            builder.Append((char) reader.Read());

        return builder.Length == 0 ? -1 : int.Parse(builder.ToString());
    }

    public double ReadDouble()
    {
        while (!char.IsDigit((char)reader.Peek()) && reader.Peek() != '.'
                                                  && reader.Peek() != -1)
        {
            reader.Read();
        }
        var builder = new StringBuilder();
        if (reader.Peek() == '.')
            builder.Append((char) reader.Read());
        while (char.IsDigit((char)reader.Peek()))
            builder.Append((char)reader.Read());
        if (reader.Peek() == '.' && !builder.ToString().Contains("."))
        {
            builder.Append((char)reader.Read());
            while (char.IsDigit((char)reader.Peek()))
                builder.Append((char)reader.Read());
        }
        return builder.Length == 0 ? -1 : double.Parse(builder.ToString());
    }

    public void Dispose()
    {
        reader.Dispose();
    }
}
1 голос
/ 03 августа 2010

Я не уверен, кто сказал вам, что их целью было использование с StringBuilder, но это абсолютно неверно.Как вы заметили, StringBuilder может считываться и записываться без использования другого класса.Классы StringWriter и StringReader расширяют базовые классы TextReader и TextWriter .Net Framework и предоставляют потоковые функции для работы с текстовыми данными.Например, если вам нужно работать с некоторыми классами типа XmlDocument, некоторые методы позволяют загружать данные Xml через TextReader, поэтому, если у вас есть текст Xml в качестве строковой переменной, вы можете загрузить его в StringReaderа затем передайте его в XmlDocument.

...