Serialize XML to byte[] instead of to file - c#

This must be very simple but I can't find it by searching.
I have the following code to serialize an object to a file and back. But now I want to serialize to a byte[] and back.
XmlSerializer serializer = new XmlSerializer(typeof(Class1));
using (TextWriter textWriter = new StreamWriter(path))
serializer.Serialize(textWriter, class1);
using (TextReader textReader = new StreamReader(path))
class1b = (Class1)serializer.Deserialize(textReader);
I tried using a MemoryStream:
byte[] buffer = new byte[1000];
using (TextWriter textWriter = new MemoryStream(buffer))
...
but I get an error. So how should I do it?

You should send the stream to the StreamWriter instead of trying to assign the Stream to a TextWriter.
using (var stream = new MemoryStream(buffer))
{
using (TextWriter textWriter = new StreamWriter(stream))
{ ... }
}

Related

How to use a string instead of a stream?

I need to use this:
http://www.newtonsoft.com/json/help/html/SerializeToBson.htm
This is code to convert object to BSON format. The code which interests me is this:
System.IO.MemoryStream stream = new System.IO.MemoryStream();
using (Newtonsoft.Json.Bson.BsonWriter writer = new Newtonsoft.Json.Bson.BsonWriter(stream))
{
Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
serializer.Serialize(writer, message);
}
However, I want the result in a string. So do I really have to use a stream or a file to write stuff in, then read it to put it in the string?
There must be a better way to do this?
You can get the string from the stream using StreamReader.ReadToEnd():
string bsonText = "";
using(MemoryStream stream = new MemoryStream())
using(StreamReader reader = new StreamReader(stream))
using (BsonWriter writer = new Newtonsoft.Json.Bson.BsonWriter(stream))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, message);
stream.Position = 0;
bsonText = reader.ReadToEnd();
}
Or also, Encoding.UTF8.GetString():
using(MemoryStream stream = new MemoryStream())
using (BsonWriter writer = new Newtonsoft.Json.Bson.BsonWriter(stream))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, message);
bsonText = Encoding.UTF8.GetString(stream.ToArray());
}
BTW who knows what you're going to get from this, since BSON is a binary object representation, it's not like JSON!

JsonSerializer failing to write to a GZipStream

I'm trying to serialize very large object directly to a zip stream. I manage to do this by serializing to a file stream in an intermediate step, loading it back and then compressing it.
I've also tried compressing directly to a memory stream and it works. But when i use a GZipStream I'm always left with an "unfinished" object, the data is there it's correctly formatted up to the point where it ends unexpectedly.
It's not for lack of flushing buffers since I've already tried flushing everything.
Simplified sample code:
internal static byte[] SerializeAndCompress(object objectToSerialize)
{
using(var memStream = new MemoryStream())
using (var zipStream = new GZipStream(memStream, CompressionMode.Compress, true))
using (var streamWriter = new StreamWriter(zipStream))
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.None };
jsonSerializer.Serialize(jsonWriter, objectToSerialize);
jsonWriter.Flush();
return memStream.ToArray();
}
}
Thanks.
Rather than flushing the writer, I suggest you close it completely. That way the GZipStream knows there's no more data to write and can add any appropriate checksums or whatever it needs to do.
You could either call Close explicitly, or put it between the closing parts of using statements:
using(var memStream = new MemoryStream())
{
using (var zipStream = new GZipStream(memStream, CompressionMode.Compress, true))
using (var streamWriter = new StreamWriter(zipStream))
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
var jsonSerializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Newtonsoft.Json.Formatting.None };
jsonSerializer.Serialize(jsonWriter, objectToSerialize);
}
return memStream.ToArray();
}
Note that by the time you call ToArray, the MemoryStream will already be closed, but that's okay - the data will still be there.

How can i Rewrite File instead of appending using StreamWriter and file stream

I want to rewrite text file using StreamWriter. but when StreamWriter uses stream (like following code), the text will append to file.
StreamWriter sw = new StreamWriter(fstream);
sw.Write(text);
sw.Close();
i must use Stream in code because of that file share limitation
FileMode.Create ll create a new file. If the file excists, it ll show exception. Use FileMode.Truncate.
string txt="your text";
using (FileStream fs = new FileStream(#"C:\Users\rajesh.kumar\Desktop\test123.txt", FileMode.Truncate))
{
using (StreamWriter writer = new StreamWriter(fs))
{
writer.Write("txt");
}
}
If you use file stream, set FileMode:
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{
using (StreamWriter writer = new StreamWriter(fs))
{
writer.Write(textToAdd);
}
}

Error reading XML file

Person person = GetPerson();
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(string.Empty, string.Empty);
XmlSerializer serializer = new XmlSerializer(typeof(Person));
string personText = string.Empty;
using (MemoryStream memoryStream = new MemoryStream())
{
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, new XmlWriterSettings() { Encoding = Encoding.UTF8 }))
{
serializer.Serialize(xmlWriter, person, ns);
xmlWriter.Flush();
personText = Encoding.UTF8.GetString(memoryStream.ToArray());
}
}
string path = #"D:\person.xml";
// Write method 1:
File.WriteAllText(path, personText);
// Write method 2:
using (StreamWriter streamWriter = new StreamWriter(path, false , Encoding.UTF8))
{
streamWriter.Write(personText);
}
// Read the xml
using (FileStream fileStream = new FileStream(path, FileMode.Open))
{
return XDocument.Load(XmlReader.Create(fileStream));
}
When I read the xml after writing using method 2, I get this Data at the root level is invalid. Line 1, position 1. But it works fine using method 1.
What is causing this? Any pointers appreciated.
The problem is that both the StreamWriter and the XmlWriter are adding a byte-order-mark.
Options:
String the BOM from personText to start with
Pass new UTF8Encoding(false) instead of Encoding.UTF8 for the StreamWriter
Pass new UTF8Encoding(false) instead of Encoding.UTF8 for the XmlWriter
Avoid converting to text and back again in the first place: you've got the binary data in the MemoryStream, why not just dump that to disk?

What is the proper way to encrypt an XmlTextWriter and serialize it to a file?

I have an XmlTextWriter that gets written to file using an XmlSerializer that looks like the following:
using (XmlTextWriter writer = new XmlTextWriter(path, null))
{
writer.Formatting = Formatting.Indented;
writer.Indentation = 3;
MyFileObj.ourSerializer.Serialize(writer, xmlFile, ourXmlNamespaces);
}
where "ourSerializer" is just a reference to an System.Xml.Serialization.XmlSerializer object. However, I have an instance where this XML must be encrypted to disk so that the end user cannot read its contents, and I am unsure of the proper way to go about it using the existing code since there are many places where this code is called and does not need to be encrypted. Can anyone shed some insight into this for me?
An alternative way would be to use a CryptoStream, like this:
using (var fs = new FileStream(path, System.IO.FileMode.Create))
{
using (var cs = new CryptoStream(fs, _Provider.CreateEncryptor(), CryptoStreamMode.Write))
{
using (var writer = XmlWriter.Create(cs))
{
writer.Formatting = Formatting.Indented;
writer.Indentation = 3;
MyFileObj.ourSerializer.Serialize(writer, xmlFile, ourXmlNamespaces);
}
}
}
Where _Provider is an AesCryptoServiceProvider properly initialized.
Here is how I ended up solving the issue:
MemoryStream ms = new MemoryStream();
XmlSerializer ourSerializer.Serialize(ms, xmlFile, ourXmlNamespaces);
ms.Position = 0;
//Encrypt the memorystream
using (TextReader reader = new StreamReader(ms, Encoding.ASCII))
using (StreamWriter writer = new StreamWriter(path))
{
string towrite = Encrypt(reader.ReadToEnd());
writer.Write(towrite);
}
Basically serialized the XML to a MemoryStream, read the text back out into a TextReader, encrypted the TextReader contents and then saved the resulting encrypted string to a file.

Categories