Вопрос по stringbuilder, c#, stream – Записать StringBuilder в поток

50

Каков наилучший метод записи StringBuilder в System.IO.Stream?

В настоящее время я делаю:

StringBuilder message = new StringBuilder("All your base");
message.Append(" are belong to us");

System.IO.MemoryStream stream = new System.IO.MemoryStream();
System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
stream.Write(encoder.GetBytes(message.ToString()), 0, message.Length);

Ваш Ответ

5   ответов
0

потому что его удобнее передавать и работать, тогда вы можете использовать что-то вроде следующего альтернативного StringBuilder, который я создал.

Самое важное, что он делает по-другому, - это то, что он позволяет получить доступ к внутренним данным без предварительной сборки их в String или ByteArray. Это означает, что вам не нужно удваивать требования к памяти и рисковать, пытаясь выделить непрерывный кусок памяти, который соответствует всему вашему объекту.

ПРИМЕЧАНИЕ: я уверен, что есть лучшие варианты, чем использованиеList<string>() внутренне, но это было просто и оказалось достаточно для моих целей.

public class StringBuilderEx
{
    List<string> data = new List<string>();
    public void Append(string input)
    {
        data.Add(input);
    }
    public void AppendLine(string input)
    {
        data.Add(input + "\n");
    }
    public void AppendLine()
    {
        data.Add("\n");
    }

    /// <summary>
    /// Copies all data to a String.
    /// Warning: Will fail with an OutOfMemoryException if the data is too
    /// large to fit into a single contiguous string.
    /// </summary>
    public override string ToString()
    {
        return String.Join("", data);
    }

    /// <summary>
    /// Process Each section of the data in place.   This avoids the
    /// memory pressure of exporting everything to another contiguous
    /// block of memory before processing.
    /// </summary>
    public void ForEach(Action<string> processData)
    {
        foreach (string item in data)
            processData(item);
    }
}

Теперь вы можете выгрузить все содержимое в файл, используя следующий код.

var stringData = new StringBuilderEx();
stringData.Append("Add lots of data");

using (StreamWriter file = new System.IO.StreamWriter(localFilename))
{
    stringData.ForEach((data) =>
    {
        file.Write(data);
    });
}
14

то-то вроде следующего:

using (MemoryStream ms = new MemoryStream())
{
    using (StreamWriter sw = new StreamWriter(ms, Encoding.Unicode))
    {
        sw.WriteLine("dirty world.");
    }
    //do somthing with ms
}
5

просто начать с StringWriter:

StringBuilder sb = null;

// StringWriter - a TextWriter backed by a StringBuilder
using (var writer = new StringWriter())
{
    writer.WriteLine("Blah");
    . . .
    sb = writer.GetStringBuilder(); // Get the backing StringBuilder out
}

// Do whatever you want with the StringBuilder
Совершенно уверен:msdn.microsoft.com/en-us/library/... Chris Moschini
5

Возможно, это будет полезно.

var sb= new StringBuilder("All your money");
sb.Append(" are belong to us, dude.");
var myString = sb.ToString();
var myByteArray = System.Text.Encoding.UTF8.GetBytes(myString);
var ms = new MemoryStream(myByteArray);
// Do what you need with MemoryStream
Сначала скопируйте в строку, затем снова скопируйте в байтовый массив, а затем, наконец, скопируйте в поток? В самом деле? Конечно, это может быть сделано кратко, без создания какой-либо промежуточной копии. (Что делать, если размер строителя составляет 2 ГБ?) Ian Goldby
76

если вы пишете в поток, сделайте это сStreamWriter:

using (var memoryStream = new MemoryStream())
using (var writer = new StreamWriter(memoryStream ))
{
    // Various for loops etc as necessary that will ultimately do this:
    writer.Write(...);
}
Также не забудьтеФлеш и искать перед чтением из потока. styfle
Абсолютно верно, но, конечно, он не сказал, что это требование, поэтому я не делал никаких предположений. Neil Barnwell
Это не возможно, если ему нужно использовать строку для чего-то еще, прежде чем писать ее. Skurmedel

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