tig*_*ars 38 c# memorystream xml-serialization xmlserializer
我正在尝试将对象写入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;
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作,流充满了字节.但是当我把它读回缓冲区然后进入字符串......缓冲区充满了'0'!不知道我在这里做错了什么.
Jon*_*eet 76
如果您检查了结果stream.Read
,您会看到它没有读取任何内容 - 因为您没有重绕流.(你可以这样做stream.Position = 0;
.)但是,它更容易调用ToArray
:
settingsString = LocalEncoding.GetString(stream.ToArray());
Run Code Online (Sandbox Code Playgroud)
(您需要更改的类型stream
从Stream
到MemoryStream
,不过没关系,因为它是在创建它的方法相同.)
或者 - 甚至更简单 - 只需使用StringWriter
而不是StreamWriter
.如果你想使用UTF-8而不是UTF-16,你需要创建一个子类,但这很容易.请参阅此答案以获取示例.
我很担心你只是捕捉Exception
并假设它意味着无害的东西,顺便说一句 - 甚至没有记录任何东西.请注意,using
语句通常比编写显式finally
块更清晰.
Far*_*d J 20
string result = System.Text.Encoding.UTF8.GetString(fs.ToArray());
Run Code Online (Sandbox Code Playgroud)
如果流长度非常大,则存在由于大对象堆而导致内存泄漏的危险。即由stream.ToArray 创建的字节缓冲区在堆内存中创建内存流的副本,从而导致保留内存的重复。我建议使用 a StreamReader
, aTextWriter
并以缓冲区块的形式读取流char
。
在netstandard2.0中System.IO.StreamReader
有一个方法ReadBlock
您可以使用此方法来读取 Stream 的实例(也是 MemoryStream 实例,因为 Stream 是 MemoryStream 的父级):
private static string ReadStreamInChunks(Stream stream, int chunkLength)
{
stream.Seek(0, SeekOrigin.Begin);
string result;
using(var textWriter = new StringWriter())
using (var reader = new StreamReader(stream))
{
var readChunk = new char[chunkLength];
int readChunkLength;
//do while: is useful for the last iteration in case readChunkLength < chunkLength
do
{
readChunkLength = reader.ReadBlock(readChunk, 0, chunkLength);
textWriter.Write(readChunk,0,readChunkLength);
} while (readChunkLength > 0);
result = textWriter.ToString();
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
注意。内存泄漏的危害并没有完全消除,由于MemoryStream的使用,可能会导致大内存流实例(memoryStreamInstance.Size>85000字节)的内存泄漏。可以使用Recyclable Memory Stream,以避免LOH。这是相关的库
小智 7
string result = Encoding.UTF8.GetString((stream as MemoryStream).ToArray());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
121140 次 |
最近记录: |