I can serialize my object in soap formatting, I wrote the directory in the string variable fullPath but when I try to deserialize it, it shows me ArgumentNullException, why?
//The code in form1.
Train tr = new Train();
fullPath = "D:\\file.xml";
tr.WriteToFile(fullPath);
//WriteToFile() method in Train class.
public void WriteToFile(string path)
{
using (FileStream stream = new FileStream(path, FileMode.Create))
{
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(stream, this);
}
}
//The code in Form2
Form1 f = new Form1();
string fullPath = f.fullPath;
try
{
using (Stream stream = File.OpenRead(f.fullPath))
{
SoapFormatter formatter = new SoapFormatter();
tr = formatter.Deserialize(stream) as Train;
}
}
catch (ArgumentNullException ex)
{
MessageBox.Show("ArgumentNullException: " + ex.Message);
}
Related
I am trying to write some json text. But I get an Exception like
The process cannot access the file C:\blah blah\SystemInActivity.json because it is being used by an other process. But then second time when I run the app after json file is created and then when I write I dont get an exception. Please help.
class ApplicationSettingsViewModel
{
ApplicationSettingsModel model;
MemoryMappedFile mmf = null;
public string FullPath = string.Empty;
//This is not a singleton class but I guess it has to be one but its ok for demonstration.
public ApplicationSettingsViewModel()
{
model = new ApplicationSettingsModel();
CreateFileWithoutMemoryMap();
//MemoryMapped();
}
public string GetDriectory()
{
return Path.GetDirectoryName(FullPath);
}
private void CreateFileWithoutMemoryMap()
{
var info = Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "/" + model.Data.Settings.OrcaUISpecificSettings.TimeOutFolder);
string path = Path.Combine(info.FullName + #"\" + model.Data.Settings.OrcaUISpecificSettings.File);
//mmf = MemoryMappedFile.CreateFromFile(path, FileMode.CreateNew, "MyMemoryFile", 1024 * 1024, MemoryMappedFileAccess.ReadWrite);
FullPath = path;
if (!File.Exists(path))
{
File.Create(path);
}
}
public void WriteToFile(string json)
{
try
{
FileStream fileStream = File.Open(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //This line giving Exception
fileStream.SetLength(0);
fileStream.Close(); // This flushes the content, too.
using (StreamWriter sw = new StreamWriter(FullPath))
{
sw.Write(json);
}
}
catch (Exception ex)
{
}
}
In the constructor of the MainWindow I am calling the write method
private ApplicationSettingsViewModel AppViewModel;
public MainWindow()
{
InitializeComponent();
//MessageBox.Show("App Started");
AppViewModel = new ApplicationSettingsViewModel();
WriteToFile("Active");
}
public void WriteToFile(string status)
{
var root = new Root();
string jsonString = string.Empty;
root.AllApplications.Add(new DataToWrite() { AppName = "DevOrca", Status = status });
try
{
jsonString = JsonConvert.SerializeObject(root, Formatting.Indented);
}
catch (Exception ex)
{
MessageBox.Show(jsonString);
MessageBox.Show("Exception");
}
mutex.WaitOne();
//Serialize Contents and write
AppViewModel.WriteToFile(jsonString);
//var access = AppViewModel.GetAccessor();
//byte[] bytes = Encoding.ASCII.GetBytes(jsonString);
//access.Write(bytes, 0, bytes.Length);
mutex.ReleaseMutex();
}
File.Create() method opens FileStream to create a file and you need to close it, something like this:
File.Create(path).Close();
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);
}
}
}
I'm trying to open and display a file that has multiple objects in it (array). I am able to open a file and display only the first object inside the file, but I want to be able to open and display all the object inside the file.
Here is how I tried it:
public T BinaryFileDeSerialize<T>(string filePath)
{
FileStream fileStream = null;
Object obj;
try
{
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
fileStream = new FileStream(filePath, FileMode.Open);
BinaryFormatter b = new BinaryFormatter(); obj = b.Deserialize(fileStream);
}
catch
{
throw;
}
finally
{
if (fileStream != null)
fileStream.Close();
}
return (T)obj;
}
MainForm:
private Animal ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
Animal str = BinSerial.BinaryFileDeSerialize<Animal>(filename);
return str;
}
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = openFileDialog1.FileName;
Animal msg = ReadFile(thefilename);
if (msg != null)
{
Resultlst.Items.Add(msg);
}
else
UpdateResults();
}
}
I'm not getting any error. The problem is that it opens and display only the first object in the file. I want it to open and display all the objects in that file.
UPDATE:
This is how I Serialized it:
public void BinaryFileSerialize(object[] objs, string filePath)
{
FileStream fileStream = null;
try
{
fileStream = new FileStream(filePath, FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
foreach (var obj in objs)
{
b.Serialize(fileStream, obj);
}
}
catch
{
throw;
}
finally
{
if (fileStream != null)
fileStream.Close();
}
}
UPDATE 2:
public T BinaryFileDeSerialize<T>(string filePath)
{
FileStream fileStream = null;
Object obj;
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
using (var thefileStream = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter b = new BinaryFormatter();
obj = b.Deserialize(thefileStream);
}
return (T)obj;
}
private Animal[] ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
var animals = BinSerial.BinaryFileDeSerialize<Animal[]>(filename);
return animals;
}
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = openFileDialog1.FileName;
Animal []msg = ReadFile(thefilename);
if (msg != null)
{
Resultlst.Items.Add(msg);
}
else
UpdateResults();
}
I'm getting error:
Failed to convert an object of type Namespace.Animal to type
System.Collections.Generic.List`1 [Namespace.Animal].
The error comes from this return (T)obj;
If you want to use the current serializer you should change deserialize methos as follow:
public IList<T> BinaryFileDeSerialize<T>(string filePath) where T: class
{
var list = new List<T>();
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
using(var fileStream = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter b = new BinaryFormatter();
while(fileStream.Position < fileStream.Length)
list.Add((T)b.Deserialize(fileStream));
}
return list;
}
And ReadFile should be like this:
private Animal[] ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
var animals = BinSerial.BinaryFileDeSerialize<Animal>(filename);
return animals.ToArray();
}
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string thefilename = openFileDialog1.FileName;
var messages = ReadFile(thefilename);
if (messages != null)
{
messages.ToList().ForEach(msg =>
Resultlst.Items.Add(msg));
}
else
{
UpdateResults();
}
}
}
Silly question, but what happens if you serialize as List<Animal> then try to call BinaryFileDeSerialize<List<Animal>>()?
Also, you can simplify your method thusly with a using statement.
public T BinaryFileDeSerialize<T>(string filePath)
{
FileStream fileStream = null;
Object obj;
if (!File.Exists(filePath))
throw new FileNotFoundException("The file" + " was not found. ", filePath);
using(var fileStream = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter b = new BinaryFormatter();
obj = b.Deserialize(fileStream);
}
return (T)obj;
}
EDIT:
Try these tweaks to your code...
//call via BinaryFileSerialize<Animal>(..., ...);
public void BinaryFileSerialize<T>(T[] objs, string filePath)
{
using(var fileStream = new FileStream(filePath, FileMode.Create))
{
BinaryFormatter b = new BinaryFormatter();
b.Serialize(fileStream, objs);
}
}
private Animal[] ReadFile(string filename)
{
BinSerializerUtility BinSerial = new BinSerializerUtility();
var animals = BinSerial.BinaryFileDeSerialize<Animal[]>(filename);
return animals;
}
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.
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);
}
}