Чтение из потока памяти в строку
Я пытаюсь написать объект в строку Xml и взять эту строку и сохранить ее в БД. Но сначала мне нужно получить строку...
private static readonly Encoding LocalEncoding = Encoding.UTF8;
public static string SaveToString<T> (T settings)
{
Stream stream = null;
TextWriter writer = null;
string settingsString = null;
try
{
stream = new MemoryStream();
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(stream, LocalEncoding);
serializer.Serialize(writer, settings);
var buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
settingsString = LocalEncoding.GetString(buffer);
}
catch(Exception ex)
{
// If the action cancels we don't want to throw, just return null.
}
finally
{
if (stream != null)
stream.Close();
if(writer != null)
writer.Close();
}
return settingsString;
}
Кажется, что это работает, поток заполняется байтами. Но когда я прихожу, чтобы прочитать его обратно в буфер, а затем в строку... буфер заполнен "0"! Не уверен, что я делаю неправильно здесь, ребята.
Ответы
Ответ 1
Если вы проверили результаты stream.Read
, вы бы увидели, что он ничего не читал, потому что вы не перематывали поток. (Вы можете сделать это с помощью stream.Position = 0;
.) Однако проще просто вызвать ToArray
:
settingsString = LocalEncoding.GetString(stream.ToArray());
(Вам нужно изменить тип stream
от stream
до MemoryStream
, но это нормально, как и в том же методе, где вы его создали.)
Альтернативно - и даже проще - просто используйте StringWriter
вместо StreamWriter
. Вам нужно будет создать подкласс, если вы хотите использовать UTF-8 вместо UTF-16, но это довольно легко. См. этот ответ для примера.
Меня беспокоит то, как вы просто ловите Exception
и считаете, что это означает что-то безвредное, кстати, даже не записывая ничего. Обратите внимание, что операторы using
обычно более чистые, чем записи явных блоков finally
.
Ответ 2
string result = System.Text.Encoding.UTF8.GetString(fs.ToArray());
Ответ 3
string result = Encoding.UTF8.GetString((stream as MemoryStream).ToArray());