C# Binaryformatter deserialize to string? - c#

I am serializing only one data to MyFile.bin file, now i have to deserialize it to a string or Int and add +1 with current value and save it again, In order to do this how to deserialize the value to Int or String variable?
Code
public void saveMember()
{
string pathMemberPk = Path.Combine(Environment.CurrentDirectory, #"../memberDataPk.bin");
if (!File.Exists(pathMemberPk)) {
memberPk = 0001;
memberPkString = memberPk.ToString();
IFormatter formatter = new BinaryFormatter();
Stream streamPk = new FileStream(pathMemberPk, FileMode.Create);
formatter.Serialize(streamPk,this.memberPkString);
}else{
using (FileStream streamIn = File.OpenRead("f://MyFile.bin"))
{
string pk;
BinaryFormatter formatter = new BinaryFormatter();
string pkk = (pk)formatter.Deserialize(streamIn).ToString();
}
}
}

I Solved Myself
public void saveMember()
{
string pathMemberPk = Path.Combine(Environment.CurrentDirectory, #"../memberDataPk.bin");
if (!File.Exists(pathMemberPk)) {
memberPk = 0001;
memberPkString = memberPk.ToString();
IFormatter formatter = new BinaryFormatter();
Stream streamPk = new FileStream(pathMemberPk, FileMode.Create);
formatter.Serialize(streamPk,this.memberPkString);
}else{
using (FileStream streamIn = File.OpenRead("f://MyFile.bin"))
{
IFormatter formatter = new BinaryFormatter();
object obj = formatter.Deserialize(streamIn);
memberPk = Convert.ToInt32(obj); //to INT
memberPk = Convert.ToString(obj); //To String
Console.WriteLine(memberPk);
}
}
}

Related

how to update a serialized bin file without earase the data that already saved?

I want to run a program that saves object by serializing it to a bin file.
The problem is, when I serialize one object to a new file, I can't add to the same file same object without erasing it.
Is there any method to serialize objects with the same type one by one, and then deserialized a list of the object?
this is the object saving:
static void Main(string[] args)
{
UserHandler.saveUser("or kandabi", "2133", "board 1");
UserHandler.saveUser("dana waizer", "21343", "board 2");
UserHandler.saveUser("elad", "4353", "board 3");
}
this is the methods for saving the object
public static void saveUser(String userName,String password,String boardId)
{
DalUser u = new DalUser(userName, password, boardId);
if (!File.Exists("userData.bin"))
{
Stream myFileStream = File.Create("userData.bin");
BinaryFormatter serializes = new BinaryFormatter();
serializes.Serialize(myFileStream, u);
myFileStream.Close();
}
else
{
Stream myFileStream = File.OpenRead("userData.bin");
BinaryFormatter serializes = new BinaryFormatter();
serializes.Serialize(myFileStream, u);
myFileStream.Close();
}
}
I expected that the data whould saved in the same "userData.bin" file, but there was an exception that the stream could not be opened for writing.
Use FileStream and FileMode.Append. Then you are able to add any object to your file and later you can read them as a list. Change your code to the following:
public static void saveUser(String userName, String password, String boardId)
{
DalUser u = new DalUser(userName, password, boardId);
using (var fileStream = new FileStream("userData.bin", FileMode.Append))
{
var bFormatter = new BinaryFormatter();
bFormatter.Serialize(fileStream, u);
}
}
public static List<DalUser> readUsers()
{
if (!File.Exists("userData.bin"))
return null;
var list = new List<DalUser>();
using (var fileStream = new FileStream("userData.bin", FileMode.Open))
{
var bFormatter = new BinaryFormatter();
while (fileStream.Position != fileStream.Length)
{
list.Add((DalUser)bFormatter.Deserialize(fileStream));
}
}
return list;
}

binary serialization to list

I used this information to convert a list to .txt with binary serialization. now I want to load that file, and put it again in my list.
this is my code to convert a list to .txt with binary serialization:
public void Save(string fileName)
{
FileStream fs = new FileStream(#"C:\" + fileName + ".txt", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, list);
fs.Close();
}
so my question is; how to convert this binary file back to a list?
You can do it like this:
//Serialize: pass your object to this method to serialize it
public static void Serialize(object value, string path)
{
BinaryFormatter formatter = new BinaryFormatter();
using (Stream fStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
formatter.Serialize(fStream, value);
}
}
//Deserialize: Here is what you are looking for
public static object Deserialize(string path)
{
if (!System.IO.File.Exists(path)) { throw new NotImplementedException(); }
BinaryFormatter formatter = new BinaryFormatter();
using (Stream fStream = File.OpenRead(path))
{
return formatter.Deserialize(fStream);
}
}
Then use these methods:
string path = #"C:\" + fileName + ".txt";
Serialize(list, path);
var deserializedList = Deserialize(path);
Thanks #Hossein Narimani Rad , I used your answer and changed it a bit (so I understand it more) and now it works.
my binair serialize method (save) is still the same.
this is my binair deserialize method (load):
public void Load(string fileName)
{
FileStream fs2 = new FileStream(fileName, FileMode.Open);
BinaryFormatter binformat = new BinaryFormatter();
if (fs2.Length == 0)
{
MessageBox.Show("List is empty");
}
else
{
LoadedList = (List<Object>)binformat.Deserialize(fs2);
fs2.Close();
List.Clear();
MessageBox.Show(Convert.ToString(LoadedList));
List.AddRange(LoadedList);
}
I know I don't have an exception now, but I understand it better this way.
I also added some code to fill my listbox with my List with the new LoadedList.

Saving multiple objects to binary file

I'm trying to save multiple object that the user create to a binary file. So far I am able to create a binary file of one object.
public class BinSerializerUtility
{
public void BinaryFileSerialize(object obj, string filePath)
{
FileStream fileStream = null;
try
{
fileStream = new FileStream(filePath, FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(fileStream, obj);
}
catch
{
throw;
}
finally
{
if (fileStream != null)
fileStream.Close();
}
}
MainForm:
private void SaveToFile(string filename)
{
for (int index = 0; index < animalmgr.Count; index++)
{
Animal animal = animalmgr.GetAt(index);
BinSerializerUtility BinSerial = new BinSerializerUtility();
BinSerial.BinaryFileSerialize(animal, filename);
}
}
private void mnuFileSaveAs_Click(object sender, EventArgs e)
{
//Show save-dialogbox
if(saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = saveFileDialog1.FileName;
SaveToFile(thefilename);
}
}
I'm not really sure how to make it so it can save multiple objects to binary file. Do you have any tips?
I did try the following:
public byte[] SerializeArray(object obj)
{
byte[] serializedObject = null;
MemoryStream memStream = null;
try
{
memStream = new MemoryStream();
BinaryFormatter binFormatter = new BinaryFormatter();
binFormatter.Serialize(memStream, obj);
memStream.Seek(0, 0); //set position at 0,0
serializedObject = memStream.ToArray();
}
finally
{
if (memStream != null)
memStream.Close();
}
return serializedObject; // return the array.
}
But the problem with it is that I don't know where to insert the fileName (The path)
You can modify BinaryFileSerialize to accept an array:
public void BinaryFileSerialize(object [] objs, string filePath). Then you can loop over that array to insert each item in the array:
FileStream fileStream = new FileStream(filePath, FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
foreach(var obj in objs) {
b.Serialize(fileStream, obj);
}
SaveToFile function:
private void SaveToFile(string filename)
{
//Animal array
Animal [] animals = new Animal[animalmgr.Count];
for (int index = 0; index < animalmgr.Count; index++)
{
animals[index] = animalmgr.GetAt(index);
}
BinSerializerUtility BinSerial = new BinSerializerUtility();
BinSerial.BinaryFileSerialize(animals, filename);
}

Reading serialized objects from binary file

I'm trying to write and read serialized objects to a binary file. I'm using Append FileMode to add serialized objects but when i try to read the file, it only print a single deserialized object.
Here's my serialization method.
public void serialize(){
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Append, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close()
}
Here's my deserialization method.
public static void read()
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject)formatter.Deserialize(stream);
stream.Close();
// Here's the proof.
Console.WriteLine("n1: {0}", obj.n1);
Console.WriteLine("n2: {0}", obj.n2);
Console.WriteLine("str: {0}", obj.str);
}
How can we loop through every single serialized record in file, like we use File.eof() or while(file.read()) in C++.
Deserialize only returns one object. You need to create a collection and loop until the end of the stream is reached:
List<MyObject> list = new List<MyObject>();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
while(stream.Position < stream.Length)
{
MyObject obj = (MyObject)formatter.Deserialize(stream);
list.add(obj);
}
The explanation above is correct, however I'd put it like this, using a collection of your like:
public static void serializeIt()
{
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
MyObject obj2 = new MyObject();
obj2.n1 = 1;
obj2.n2 = 24;
obj2.str = "Some other String";
List<MyObject> list = new List<MyObject>();
list.Add(obj);
list.Add(obj2);
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Append,FileAccess.Write, FileShare.None);
formatter.Serialize(stream, list);
stream.Close();
}
public static void read()
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
List<MyObject> list = (List<MyObject>)formatter.Deserialize(stream);
stream.Close();
}
You should also make sure that the MyFile.bin is rewriten each time you serialize your collection, as it would always return the collection that was saved first if you'd keep appending them. That should be the only downside.
Thank you for your help, I made this.
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
private static Dictionary<int, ArrayList> J1_CarteDeck;
private static string PathDocuments = String.Format("{0}\\Antize Game\\", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
private const string FILE_NAME = "Antize.data";
public static bool SauvegarderDeck()
{
if (!(Directory.Exists(PathDocuments)))
Directory.CreateDirectory(PathDocuments);
if (File.Exists(PathDocuments + FILE_Deck))
File.Delete(PathDocuments + FILE_Deck);
foreach (ArrayList child in J1_CarteDeck.Values)
{
if(child != null)
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(PathDocuments + FILE_Deck, FileMode.Append, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, child);
stream.Close();
}
}
if (File.Exists(PathDocuments + FILE_Deck))
return true;
else
return false;
}
public static bool ChargerDeck()
{
if (!(File.Exists(PathDocuments + FILE_Deck)))
return false;
int cptr = 1;
J1_CarteDeck = new Dictionary<int, ArrayList>();
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(PathDocuments + FILE_Deck, FileMode.Open, FileAccess.Read, FileShare.None);
while (stream.Position < stream.Length)
{
J1_CarteDeck[cptr] = (ArrayList)formatter.Deserialize(stream);
cptr++;
}
stream.Close();
return true;
}
Simply iterate through each object in binary file
using (System.IO.FileStream fs = new System.IO.FileStream("D:\\text\\studentdata.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter sf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Object o = sf.Deserialize(fs);
while (fs.Position < fs.Length)
{
o = sf.Deserialize(fs);
Student student = (o as Student);
Console.WriteLine("str: {0}", student.sname);
}
}

"Binary stream does not contain a valid BinaryHeader" error on (de)serialization?

I am created a post before " Object to byte not working " .
I fixed problems that users said me , but there is still problem .
Error Message : The constructor to deserialize an object of type 'WindowsFormsApplication1.Form1+Item' was not found.;
void start()
{
Item item = new Item();
item.files.Add(#"test");
byte[] b = ObjectToByteArray(item);
Item k = Desriles(b);
}
[Serializable]
public class Item : ISerializable
{
public Item()
{
files = new List<string>();
Exclude = false;
CleanEmptyFolder = false;
}
public List<string> files;
public string MusicProfileName;
public bool Exclude;
#region ISerializable Members
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("files", files);
info.AddValue("MusicProfileName", MusicProfileName);
info.AddValue("Exclude", Exclude);
}
#endregion
}
public byte[] ObjectToByteArray(object _Object)
{
using (var stream = new MemoryStream())
{
// serialize object
var formatter = new BinaryFormatter();
formatter.Serialize(stream, _Object);
// get a byte array
var bytes = new byte[stream.Length];
using (BinaryReader br = new BinaryReader(stream))
{
bytes = br.ReadBytes(Convert.ToInt32(stream.Length));
}
return bytes;
}
}
public Item Desriles(byte[] items)
{
using (MemoryStream stream = new MemoryStream())
{
stream.SetLength(items.LongLength);
stream.write(items, 0, items.Length);
var formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
object item = formatter.Deserialize(stream); // Here I will get error
return (Item)item;
}
}
The serialization code can't work properly, you forgot to reset the stream back to the beginning. The better mouse trap:
public byte[] ObjectToByteArray(object _Object) {
using (var stream = new MemoryStream()) {
var formatter = new BinaryFormatter();
formatter.Serialize(stream, _Object);
return stream.ToArray();
}
}
The deserialization code can similarly be simplified:
public Item Desriles(byte[] items) {
using (MemoryStream stream = new MemoryStream(items)) {
var formatter = new BinaryFormatter();
return (Item)formatter.Deserialize(stream);
}
}
And you don't need GetObjectData().
In this section:
using (MemoryStream stream = new MemoryStream())
{
stream.SetLength(items.LongLength);
stream.Read(items, 0, items.Length);
[...]
object item = formatter.Deserialize(stream);
it seems you are creating a new, empty memory stream, then attempting to read from it, and Deserialize from it.
Of course it fails. The stream is empty.
abelenky makes a good point, but I don't think your:
public byte[] ObjectToByteArray(object _Object)
works either.
C# Code Snippet - Object to byte array
C# Code Snippet - Byte array to object
Thanks to All :
I found problem : I should base that to ISerializable

Categories

Resources