В чем разница между вызовом Stream.Write и использованием StreamWriter?

В чем разница между созданием объекта Stream, например MemoryStream, и вызовом метода memoryStream.Write() для записи в поток и создания экземпляра объекта StreamWriter с потоком и вызова streamWriter.Write()?

Рассмотрим следующий сценарий:

У вас есть метод, который принимает поток, записывает значение и возвращает его. Поток читается позже, поэтому позиция должна быть reset. Есть два возможных способа сделать это (оба, похоже, работают).

// Instantiate a MemoryStream somewhere
//     - Passed to the following two methods
MemoryStream memoryStream = new MemoryStream();

// Not using a StreamWriter
private static Stream WriteToStream(Stream stream, string value)
{
    stream.Write(Encoding.Default.GetBytes(value), 0, value.Length);
    stream.Flush();
    stream.Position = 0;
    return stream;
}

// Using a StreamWriter
private static Stream WriteToStreamWithWriter(Stream stream, string value)
{
    StreamWriter sw = new StreamWriter(stream);
    sw.Write(value, 0, value.Length);
    sw.Flush();
    stream.Position = 0;
    return stream;
}

Это частично проблема с областью, поскольку я не хочу закрывать поток после его записи, поскольку он будет прочитан позже. Я тоже, конечно, тоже не хочу его уничтожать, потому что это закроет мой поток. Разница, похоже, заключается в том, что не использование StreamWriter вводит прямую зависимость от Encoding.Default, но я не уверен, что это очень большая сделка. Какая разница, если таковая имеется?

Ответ 1

С StreamWriter у вас более высокие уровни перегрузки, которые могут писать различные типы в поток, не беспокоясь о деталях. Например, ваш код

sw.Write(value, 0, value.Length);

Может быть просто

sw.Write(value);

Использование перегрузки StreamWriter.Write(string).

Ответ 2

Единственное отличие состоит в том, что new StreamWriter(stream) по умолчанию использует кодировку UTF-8, поэтому он будет поддерживать данные Unicode. Encoding.Default (по крайней мере, на моем компьютере) является кодовой страницей фиксированного размера (например, Windows-1250) и поддерживает только ASCII и ограниченный набор национальных символов (всего 256 различных символов).

Вы действительно не должны делать следующее:

stream.Write(encoding.GetBytes(value), 0, value.Length);

Это просто совпадение, что используемая кодировка имеет фиксированный размер в 1 байт. (Это не будет работать с UTF-16 или с данными UTF-8 и не-ASCII.) Вместо этого, если вам нужно напрямую записать в поток, выполните:

byte[] byteData=encoding.GetBytes(value);
stream.Write(byteData, 0, byteData.Length);

Ответ 3

В терминах byte[] массивов ничего, StreamWriter не вводит другие более полезные методы, хотя для работы с другими типами.

Ответ 4

StreamWriter - это суперкласс Stream, который реализует TextWriter для упрощения обработки текста. Но поскольку это суперкласс, он имеет все те же методы в дополнение к обработке текста. Вот почему в первом примере вам нужно Encoding.Default.GetBytes(значение), а во втором - нет.