Can anyone tell me how to use Salar Bois serialization to disk?
I want to do the right thing since I'm optimizing both by size and time.
Specifically I had to serialize a List lp;
All what I find on the site is:
How to serialize an object:
var boisSerializer = new BoisSerializer();
using (var mem = new MemoryStream())
{
boisSerializer.Serialize(this, mem);
return mem.ToArray();
}
How to deserialize an object:
var boisSerializer = new BoisSerializer();
return boisSerializer.Deserialize<SampleObject>(dataStream);
Thanks
Patrick
Basically, you want to use a FileStream instead of a MemoryStream.
There's an example at the bottom of this MSDN page:
https://msdn.microsoft.com/en-us/library/system.io.filestream(v=vs.110).aspx
To use your code example however:
var boisSerializer = new BoisSerializer();
using (var fileStream = File.Create("c:\myfile.obj"))
{
boisSerializer.Serialize(this, fileStream);
}
Clearly, your return object will change, so you'll have to account for how you're using this code.
Related
I have implemented a code block in order to convert Stream into Byte Array. And code snippet is shown below. But unfortunately, it gives OutOfMemory Exception while converting MemoryStream to Array (return newDocument.ToArray();). please could someone help me with this?
public byte[] MergeToBytes()
{
using (var processor = new PdfDocumentProcessor())
{
AppendStreamsToDocumentProcessor(processor);
using (var newDocument = new MemoryStream())
{
processor.SaveDocument(newDocument);
return newDocument.ToArray();
}
}
}
public Stream MergeToStream()
{
return new MemoryStream(MergeToBytes());
}
Firstly: how big is the document? if it is too big for the byte[] limit: you're going to have to use a different approach.
However, a MemoryStream is already backed by an (oversized) array; you can get this simply using newDocument.TryGetBuffer(out var buffer), and noting that you must restrict yourself to the portion of the .Array indicated by .Offset (usually, but not always, zero) and .Count (the number of bytes that should be considered "live"). Note that TryGetBuffer can return false, but not in the new MemoryStream() scenario.
If is also interesting that you're converting a MemoryStream to a byte[] and then back to a MemoryStream. An alternative here would just have been to set the Position back to 0, i.e. rewind it. So:
public Stream MergeToStream()
{
using var processor = new PdfDocumentProcessor();
AppendStreamsToDocumentProcessor(processor);
var newDocument = new MemoryStream();
processor.SaveDocument(newDocument);
newDocument.Position = 0;
return newDocument;
}
I have a bit of C# code which I use for performing a deep copy of an object:
public static T Copy<T>(T objectToCopy)
{
T result = default(T);
using (var memoryStream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(memoryStream, objectToCopy);
memoryStream.Seek(0, SeekOrigin.Begin);
result = (T)formatter.Deserialize(memoryStream);
memoryStream.Close();
}
return result;
}
I get this warning from Visual Studio:
Warning SYSLIB0011
'BinaryFormatter.Serialize(Stream)' is obsolete: 'BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.'
I get the same warning about BinaryFormatter.Deserialize(Stream).
I've looked at the suggested link, and they list some preferred alternatives:
XmlSerializer and DataContractSerializer to serialize object graphs into and from XML. Do not confuse DataContractSerializer with NetDataContractSerializer.
BinaryReader and BinaryWriter for XML and JSON.
The System.Text.Json APIs to serialize object graphs into JSON.
I'm just struggling to figure out in my specific case how I would implement one of those alternatives.
If anyone could assist me in this I would greatly appreciate it.
Thank you.
When I tried this code on server(after local) it is failed because of filepath changes on it. How can I hold xmldoc object on buffer or somewhere else before writing? If I can write to buffer, no need to filepath and it will be independent from a path. Or anyone suggest a different way?
const string fileName = "123.xml";
string filePath = Server.MapPath("123.xml");
var xmlDoc = new StreamWriter(filePath);
dataSet.WriteXml(xmlDoc);
xmlDoc.Close();
Here's a reference on using a MemoryStream in conjunction with Xml Documents:
http://blogs.msdn.com/b/tolong/archive/2007/11/15/read-write-xml-in-memory-stream.aspx
You could use this constructor : StreamWriter Constructor (Stream) overload and use a MemoryStream
You can try something like
using (var stream = new MemoryStream())
{
var sw = new StreamWriter(stream);
Don't know if this is what you're looking for but I use memory mapped files to manage temp data. Here is a great article, short and with working examples.
I need to save an object, its serializable but I donot want to use XML.
Is it possible to write the raw bytes of the object and then read it off the disk to create the object again?
Thanks for the help!
Use a BinaryFormatter:
var formatter = new BinaryFormatter();
// Serialize
using (var stream = File.OpenWrite(path))
{
formatter.Serialize(stream, yourObject);
}
...
// Deserialize
using (var stream = File.OpenRead(path))
{
YourType yourObject = (YourType)formatter.Deserialize(stream);
}
Yes, it is called binary serialization. There are some good examples on the MSDN site:
http://msdn.microsoft.com/en-us/library/4abbf6k0(v=vs.100).aspx
this is simple I know, but i don't have internet access and this netcafes keyboard sucks, so if someone can answer this question please.
what would be the class ? just give me a kick in the right direction. there is simple arraylist object that I want to write and read to/ from file.
thanks
There's no single definitive answer to this question. It would depend on the format of the file and the objects in the list. You need a serializer. For example you could use BinaryFormatter which serializes an object instance into a binary file but your objects must be serializable. Another option is the XmlSerializer which uses XML format.
UPDATE:
Here's an example with BinaryFormatter:
class Program
{
static void Main()
{
var list = new ArrayList();
list.Add("item1");
list.Add("item2");
// Serialize the list to a file
var serializer = new BinaryFormatter();
using (var stream = File.OpenWrite("test.dat"))
{
serializer.Serialize(stream, list);
}
// Deserialize the list from a file
using (var stream = File.OpenRead("test.dat"))
{
list = (ArrayList)serializer.Deserialize(stream);
}
}
}
Since you did not mention what type of data this array contains, I would suggest writing the file in binary format.
Here is a good tutorial on how to read and write in binary format.
Basically, you need to use BinaryReader and BinaryWriter classes.
[Edited]
private static void write()
{
List<string> list = new List<string>();
list.Add("ab");
list.Add("db");
Stream stream = new FileStream("D:\\Bar.dat", FileMode.Create);
BinaryWriter binWriter = new BinaryWriter(stream);
binWriter.Write(list.Count);
foreach (string _string in list)
{
binWriter.Write(_string);
}
binWriter.Close();
stream.Close();
}
private static void read()
{
List<string> list = new List<string>();
Stream stream = new FileStream("D:\\Bar.dat", FileMode.Open);
BinaryReader binReader = new BinaryReader(stream);
int pos = 0;
int length = binReader.ReadInt32();
while (pos < length)
{
list.Add(binReader.ReadString());
pos ++;
}
binReader.Close();
stream.Close();
}
If your objects in the arraylist are serializable, you can opt for binary serialization. But this means any other application need to know the serialization and then only can use this files. You may like to clarify your intent of using the serialization. So the question remains, why do you need to do a serialization? If it is simple, for you own (this application's) use, you can think of binary serialization. Be sure, your objects are serializable. Otherwise, you need to think of XML serialization.
For Binary serialization, you can think of some code like this:
Stream stream = File.Open("C:\\mySerializedData.Net", FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(stream, myArray);
stream.Close();