How do I deserialize a binary file to a string?
This is my sample code so far:
public function serialize()
{
FileStream fs = new FileStream("test.txt", FileMode.Append);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, textBox1.Text);
fs.Flush();
fs.Close();
}
public function deserialize()
{
FileStream fs = File.Open(openFileDialog1.FileName, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
richTextBox1.Text = formatter.Deserialize(mystream) as string;
fs.Flush();
fs.Close();
}
When I start to debug the application, it only shows the first string of the stream. The rest of the stream did not show up. How should I fix this?
Just use
System.IO.File.WriteAllText(fileName, textBox1.Text);
and
textBox1.Text = System.IO.File.ReadAllText(fileName);
The right way to do this is to put all of the values that you want to serialize into a serializable structure and then serialize that structure. On the other end you deserialize that structure and then put the values where they need to go.
Note that the binary serializer produces binary, not text output. If you want human readable serialized data you can use the XmlSerializer instead.
Binary serialization serializes object graphs; it doesn't just write strings.
It wouldn't make sense to combine object graphs.
You should read and write the file directly using the File class.
Related
I have a list of events and I save it in a binary file using this code
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
{
using (BinaryWriter w = new BinaryWriter(fs))
{
foreach (MacroEvent macroEvent in events)
{
w.Write(macroEvent.TimeSinceLastEvent);
}
}
}
but I'm confused to how I read and get it back again in a list?
The following recipe is a good guide on how to implement ISerializable for an object you want to serialize and deserialize with a BinaryFormatter:
http://www.switchonthecode.com/tutorials/csharp-tutorial-serialize-objects-to-a-file
Here is the NET 4.0 documentation on BinaryFormatter:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx
and ISerializable:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx
Sequential file access File using serialization
Add
Using system.Io
Using system.Runtime.Serialzation.Formatters.Binary
Using System.Runtime.Serialization
Using Macro Events
name space created fileform : macroform
//Object For serializing RecordSerializables in binary format
Private Binary formatter = new binaryFormatter();
Private file stream output; //stream for writing to a file
Use method Deserialize to read data
Cast result of Deserialize to type serializeable to type serializeable this cast is necessary ,because Deserialize returns a refrence of type object and need to access properties that belong to class serializable. If an error during deserialization is thrown
a serialization is thrown and the file stream is closed
Private BinaryFormatter eader = new BinaryFormatter();
Private File stream input; // stream for reading from file
I'm having trouble deserializing my XML file from a MemoryStream. I have a generated MyXmlFile class and a MemoryStream containing an XML file which I want to deserialize into an object of type MyXmlFile.
public static class XmlSerializeObject
{
public static T FromStream<T>(Stream s)
{
var serializer = new XmlSerializer(typeof(T));
return (T) serializer.Deserialize(s);
}
}
I have a MemoryStream ms which contains an xml file. If I try to deserialize that stream into an object of type MyXmlFile I get an exception "There is an error in XML document (0,0)"
MyXmlFile test = XmlSerializeObject.FromStream<MyXmlFile>(ms);
However I verified that my MemoryStream is correct. If I first write my stream into a file on my disc and than read that file again it works fine.
FileStream outStream = File.OpenWrite("D:\\p.xml");
outStream.Write(((MemoryStream)ms).ToArray(), 0, ((MemoryStream)ms).ToArray().Length);
outStream.Flush();
outStream.Close();
MyXmlFile test= XmlSerializeObject.FromStream<MyXmlFile>(File.OpenRead("D:\\p.xml"));
I was not able to find a solution myself that is why I decided to post my question. Maybe someone had the same problem before and is able to help me out.
Thanks in advance. If anything is unclear please ask.
If you instantiated your memory stream prior to your call to deserialize (say, to load the XML into the memory stream in the first place) it may be that it's at the wrong index. Try
ms.Seek(0, SeekOrigin.Begin)
To go back to the beginning of the stream.
You must set position of MemoryStream to the 0.
((MemoryStream)ms).Position = 0;
MyXmlFile test = XmlSerializeObject.FromStream<MyXmlFile>(ms);
I have a collection of objects at runtime, which is already serializable, I need to persist the state of the object to a file. I did a quick coding using BinaryFormatter and saved A serialized object to a file.
I was thinking that I can save object per line. but when i open the file in a notepad, it was longer than a line. It wasnt scrolling. How can i store an binary serialized object per line?
I am aware that i can use a separator after each object so while reading them back to the application, i can know the end of the object. Well, according to information theory, this increases the size of the data(Sipser book).
What s the best algorithm to come up with a separator that woudldnt break the information?
Instead of binary serialization? Do you think JSon format is more feasible? can i store the entity in a json format, line by line?
Also, serialization/deserialization introduces overhead, hits the performance. Would Json be faster?
ideas?
Thanks.
Thanks.
Serialization functions like a FIFO queue, you dont have to read parts of the file because the formatter does it for you you just have to know the order you pushed objects inside.
public class Test
{
public void testSerialize()
{
TestObj obj = new TestObj();
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
formatter.Serialize(stream, 1);
formatter.Serialize(stream, DateTime.Now);
stream.Close();
}
public void TestDeserialize()
{
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.None);
IFormatter formatter = new BinaryFormatter();
TestObj obj = (TestObj)formatter.Deserialize(stream);
int obj2 = (int)formatter.Deserialize(stream);
DateTime dt = (DateTime)formatter.Deserialize(stream);
stream.Close();
}
}
[Serializable]
class TestObj
{
public string str = "1";
int i = 2;
}
Well,
Serialization/deserialization introduces overhead, would Json be faster?
JSON is still a form of serialisation, and no it probably wouldn't be faster than binary serialisation - binary serialisation is intended to be compact and quick, wheras JSON serialisation puts more emphasis on readability and so many be slower as is very likely to be less compact.
You could serialise each object individually and emit some separator between each object (e.g. a newline character), but I don't know what separator you could use that is guarenteed to not appear in the serialised data (what happens if you serialise a string containing a newline character?).
If you use a separator that the .Net serialisation framework emits then obviously you will make it difficult (if not impossible) to correctly determine where the breaks between objects are leading to deserialisation failures.
Why exactly do you want to put each object on its own line?
Binary serialization saves the data to arbitrary bytes; these bytes can include newline characters.
You're asking to use newlines as separators. Newlines are no different from other separators; they will also increase the size of the data.
You could also create a ArrayList and add the objects to it and then serialize it ;)
ArrayList list = new ArrayList();
list.Add(1);
list.Add("Hello World");
list.Add(DateTime.Now);
BinaryFormatter bf = new BinaryFormatter();
FileStream fsout = new FileStream("file.dat", FileMode.Create);
bf.Serialize(fsout, list);
fsout.Close();
FileStream fsin = new FileStream("file.dat", FileMode.Open);
ArrayList list2 = (ArrayList)bf.Deserialize(fsin);
fsin.Close();
foreach (object o in list2)
Console.WriteLine(o.GetType());
I'm trying to serialize/deserialize string. Using the code:
private byte[] StrToBytes(string str)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, str);
ms.Seek(0, 0);
return ms.ToArray();
}
private string BytesToStr(byte[] bytes)
{
BinaryFormatter bfx = new BinaryFormatter();
MemoryStream msx = new MemoryStream();
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
return Convert.ToString(bfx.Deserialize(msx));
}
This two code works fine if I play with string variables.
But If I deserialize a string and save it to a file, after reading the back and serializing it again, I end up with only first portion of the string.
So I believe I have a problem with my file save/read operation. Here is the code for my save/read
private byte[] ReadWhole(string fileName)
{
try
{
using (BinaryReader br = new BinaryReader(new FileStream(fileName, FileMode.Open)))
{
return br.ReadBytes((int)br.BaseStream.Length);
}
}
catch (Exception)
{
return null;
}
}
private void WriteWhole(byte[] wrt,string fileName,bool append)
{
FileMode fm = FileMode.OpenOrCreate;
if (append)
fm = FileMode.Append;
using (BinaryWriter bw = new BinaryWriter(new FileStream(fileName, fm)))
{
bw.Write(wrt);
}
return;
}
Any help will be appreciated.
Many thanks
Sample Problematic Run:
WriteWhole(StrToBytes("First portion of text"),"filename",true);
WriteWhole(StrToBytes("Second portion of text"),"filename",true);
byte[] readBytes = ReadWhole("filename");
string deserializedStr = BytesToStr(readBytes); // here deserializeddStr becomes "First portion of text"
Just use
Encoding.UTF8.GetBytes(string s)
Encoding.UTF8.GetString(byte[] b)
and don't forget to add System.Text in your using statements
BTW, why do you need to serialize a string and save it that way?
You can just use File.WriteAllText() or File.WriteAllBytes. The same way you can read it back, File.ReadAllBytes() and File.ReadAllText()
The problem is that you are writing two strings to the file, but only reading one back.
If you want to read back multiple strings, then you must deserialize multiple strings. If there are always two strings, then you can just deserialize two strings. If you want to store any number of strings, then you must first store how many strings there are, so that you can control the deserialization process.
If you are trying to hide data (as indicated by your comment to another answer), then this is not a reliable way to accomplish that goal. On the other hand, if you are storing data an a user's hard-drive, and the user is running your program on their local machine, then there is no way to hide the data from them, so this is as good as anything else.
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();