StringBuilder Vs StringWriter / StringReader

Ostatnio czytałem, że w StringWriter i StringReader są używane do pisania i czytania z StringBuilder.

Cóż, kiedy używam StringBuilder obiekt, wygląda na samowystarczalną klasę.

Mamy każdy sposób czytania i pisania StringBuilder, używając StringBuilder.Append(), Insert(), Replace(), Remove() itd...

  1. Jakie jest możliwe użycie StringWriter i StringReader, czego nie można zrobić samemu StringBuilder?
  2. jakie jest ich praktyczne zastosowanie?
  3. jaki może być powód, dla którego nie biorą w górę Stream jako wejście (ponieważ każdy inny writer i czytnik biorą strumień jako parametr konstruktora do działania), ale StringBuilder?
Author: Pragmateek, 2010-08-03

4 answers

Jakie jest możliwe użycie StringWriter i StringReader, czego nie można zrobić za pomocą samego Stringbuildera?

StringReader i StringWriter pochodzą odpowiednio z TextReader i TextWriter. Więc co mogą zrobić, działać jako TextReader lub TextWriter instancja, której string lub StringBuilder nie mogą, ponieważ nie wywodzą żadnego z tych typów.

Jakie jest ich praktyczne zastosowanie?

Pozwalają na wywołanie API, które oczekują TextReader lub TextWriter, gdy to, co masz / chcesz jest string lub StringBuilder.

Jaki może być powód, dla którego nie zajmują Stream jako wejścia (ponieważ każdy inny writer i czytnik biorą stream jako parametr konstruktora, na którym mają działać), ale StringBuilder?

Ponieważ nie działają na strumieniach; działają na string s lub StringBuilder s. są to po prostu proste klasy wrapperów, które dostosowują te typy do API oczekujących innego interfejsu. Zobacz: wzór adaptera .

 32
Author: Greg Beech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 00:38:10

Inni już mówili, ale dzieje się tak dlatego, że wywodzą się z TextReader/TextWriter i mogą być używane zamiast nich. Po pierwsze, bardziej sensowne jest użycie tej samej metody do wyprowadzania linii, której używasz w pliku, jeśli chcesz, aby zawartość była tylko ciągiem znaków. Jeśli chcesz, aby wyjście obejmowało wiele linii w pamięci, po co zapamiętywać umieszczenie" \R\n " na końcu każdej linii za pomocą Stringbuildera? Co zrobić, jeśli chcesz, aby Kod był uruchamiany lub formatował dane dla systemu, który używa tylko "\n " dla przerw w linii?

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);

Powiedzmy, że chcesz przetworzyć plik linia po linii, prawdopodobnie użyłbyś Streamreadera zamiast ładować cały plik do Stringbuildera i dzielić go znakami nowej linii na tablicę, prawda? Z StringReader możesz użyć dokładnie tej samej metody (tak długo, jak trwa ogólny TextReader), tworząc StringReader z łańcucha z pola tekstowego lub formularza internetowego.

Linq2sql DataContext mają właściwość Log, którą można ustawić na TextWriter Twoje zapytania wyjściowe przed ich wykonaniem, aby zobaczyć dokładnie, co jest uruchamiane. Możesz ustawić to na Edytor tekstu dołączony do pliku, ale możesz dołączyć do niego napis StringWriter i wypisać zawartość u dołu strony internetowej podczas testowania...

 5
Author: Jason Goemaat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-30 04:57:48

Nie jestem pewien, kto powiedział ci, że ich celem było użycie z StringBuilder, ale jest to absolutnie błędne. Jak zauważyłeś StringBuilder może być odczytywany i zapisywany bez użycia innej klasy. Klasy StringWriter i StringReader rozszerzają klasy bazowe TextReader i TextWriter. Net Framework i zapewniają funkcje podobne do strumienia do pracy z danymi tekstowymi. Na przykład, jeśli chcesz pracować z niektórymi klasami typu XmlDocument, niektóre metody pozwalają załadować Dane Xml poprzez TextReader, więc jeśli masz tekst Xml jako zmienną łańcuchową, możesz załadować go do Stringreadera, a następnie dostarczyć go do XmlDocument.

 1
Author: EchoCoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-03 00:35:38

Możesz użyć StringReader do odczytu wszystkich liczb całkowitych z ciągu znaków.

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);
        }
    }
}

Klasa StandardInput:

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
Author: Raz Megrelidze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 13:35:56