I saved the data as shown below, now I want to restore the XML data into the corresponding text boxes.
CustomerData customer = new CustomerData();
customer.FirstName = first_name.Text;
customer.RegNo = reg_no.Text;
customer.Department = dept.Text;
XmlSerializer xs = new XmlSerializer(typeof(CustomerData));
using(FileStream fs = new FileStream(#"D:\Data.xml", FileMode.Create)) {
xs.Serialize(fs, customer);
}
MessageBox.Show("Inserted");
XmlSerializer xs = new XmlSerializer(typeof(CustomerData));
using(FileStream fs = new FileStream(#"D:\Data.xml", FileMode.Open))
{
CustomerData customer = (CustomerData)xs.Deserialize(fs);
first_name.Text = customer.FirstName;
reg_no.Text = customer.RegNo;
dept.Text = customer.Department;
}
UPDATE If you want to save history of customer data changes and load last one, then save and load list of CustomerData objects:
private List<CustomerData> GetCustomers(string filename)
{
if (!File.Exists(filename))
return new List<CustomerData>();
XmlSerializer xs = new XmlSerializer(typeof(List<CustomerData>));
using (FileStream fs = new FileStream(filename, FileMode.Open))
return (List<CustomerData>)xs.Deserialize(fs);
}
public void SaveCustomers(string filename, List<CustomerData> customers)
{
XmlSerializer xs = new XmlSerializer(typeof(List<CustomerData>));
using (FileStream fs = new FileStream(filename, FileMode.Create))
xs.Serialize(fs, customers);
}
And use it to save:
List<CustomerData> customers = GetCustomers(#"D:\Data.xml");
CustomerData customer = new CustomerData();
customer.FirstName = first_name.Text;
customer.RegNo = reg_no.Text;
customer.Department = dept.Text;
customers.Add(customer);
SaveCustomers(#"D:\Data.xml", customers);
And load:
var customer = GetCustomers(#"D:\Data.xml").LastOrDefault();
if (customer != null)
{
first_name.Text = customer.FirstName;
reg_no.Text = customer.RegNo;
dept.Text = customer.Department;
}
Related
using (var fileStream = new FileStream("data.bin", FileMode.Append, FileAccess.Write))
using (var bw1 = new BinaryWriter(fileStream))
{
bw1.Write(jmeno);
bw1.Write(date);
bw1.Write(rodnecislo);
bw1.Write(sarze);
}
using (var fileStream = new FileStream("data.bin", FileMode.Open, FileAccess.Read))
using (var br1 = new BinaryReader(fileStream))
{
string readname = br1.ReadString();
int readdate = br1.ReadInt32();
long readcislo = br1.ReadInt64();
long readsarze = br1.ReadInt64();
Console.WriteLine(readname);
Console.WriteLine(readdate);
Console.WriteLine(readcislo);
Console.WriteLine(readsarze);
}
This is how the BinaryWriter looks like. I don't know how to make the console write this whole binary file.
OK, then here is how to do it:
using (var fileStream = new FileStream("data.bin", FileMode.Open, FileAccess.Read))
using (var br1 = new BinaryReader(fileStream))
{
while (br1.BaseStream.Position != br1.BaseStream.Length)
{
string readname = br1.ReadString();
int readdate = br1.ReadInt32();
long readcislo = br1.ReadInt64();
long readsarze = br1.ReadInt64();
Console.WriteLine(readname);
Console.WriteLine(readdate);
Console.WriteLine(readcislo);
Console.WriteLine(readsarze);
}
}
For an explanation of the while condition see e.g. here
I have the following code to serialize decrypted and deserialize encrypted objects from a binary file. Writing decrypted objects works well. However, when attempting to de-serialize decrypted objects from the file, it fails after the first object successfully de-serialized.
I was hoping that someone could point me to the error, as I ran out of ideas.
Writing encrypted objects to a binary file works perfectly well
public List ReadAllObjectsFromFile(string pPath)
{
List objList = null;
T obj = default(T);
using (FileStream stream = new FileStream(pPath, FileMode.Open, FileAccess.Read))
{
while (true)
{
if (stream.Length>m_ReaderPosition)
{
stream.Seek(m_ReaderPosition, SeekOrigin.Begin);
if (IsEncrypted)
{
using (Stream cryptoStream = new CryptoStream(stream, m_Decryptor, CryptoStreamMode.Read))
{
if (objList == null) objList = new List();
obj = (T)m_Formatter.Deserialize(cryptoStream);
}
}
else
{
if (objList == null) objList = new List();
obj = (T)m_Formatter.Deserialize(stream);
}
m_ReaderPosition = stream.Position;
}
if ((IsReadToEnd = object.Equals(obj, default(T)))) break;
else
{
objList.Add(obj);
obj = default(T);
}
}
}
return objList;
}
Trying to read the encrypted objects from the binary file and deserialize them into de-crypted objects throw as exception at the second object it attempts to deserialize
"System.Runtime.Serialization.SerializationException: 'The input
stream is not a valid binary format. The starting contents (in bytes)
are: 83-AD-D4-BB-F9-7A-4E-34-C2-E7-4F-0C-4F-51-F2-1E-EC .."
The method successfully de-serialized the first object though.
This line of code triggers the exception on second object.
obj = (T)m_Formatter.Deserialize(cryptoStream);
public List ReadAllObjectsFromFileEnc(string pPath)
{
List objList = null;
T obj = default(T);
using (FileStream stream = new FileStream(pPath, FileMode.Open, FileAccess.Read))
{
using (Stream cryptoStream = new CryptoStream(stream, m_Decryptor, CryptoStreamMode.Read))
{
while (true)
{
if (stream.Length>m_ReaderPosition)
{
stream.Seek(m_ReaderPosition, SeekOrigin.Begin);
if (objList == null) objList = new List();
obj = (T)m_Formatter.Deserialize(cryptoStream);
m_ReaderPosition = stream.Position;
}
if ((IsReadToEnd = object.ReferenceEquals(obj, default(T)))) break;
else
{
objList.Add(obj);
obj = default(T);
}
}
}
return objList;
}
}
Main
static void Main(string[] args)
{
List objList = new List();
objList.Add(
new Bear()
{
Name = "John",
Age = 35,
Birth = new DateTime(1977, 02, 02),
Females = new KeyValuePair("Dove", "Mumu")
});
objList.Add(
new Bear()
{
Name = "Max",
Age = 40,
Birth = new DateTime(1977, 08, 02),
Females = new KeyValuePair("Gr", "Mumu")
});
objList.Add(
new Bear()
{
Name = "Mika",
Age = 21,
Birth = new DateTime(1990, 02, 02),
Females = new KeyValuePair("Dr", "Mumu")
});
objList.Add(
new Bear()
{
Name = "Miles",
Age = 90,
Birth = new DateTime(1901, 02, 02),
Females = new KeyValuePair("SE", "Mumu")
});
BinarySerializer binser = new BinarySerializer(#"E:\Temp\myFile.bin", 10000, true, "My Encryption is here");
foreach(Bear t in objList)
binser.WriteObjectToFile(binser.FileDetails.FullName, t);
objList = null;
objList = binser.ReadAllObjectsFromFileEnc(binser.FileDetails.FullName);
}
Here's the write to file
public void WriteObjectToFile(string pPath, object pObject)
{
using (FileStream stream = new FileStream(pPath, FileMode.Append, FileAccess.Write))
{
if (IsEncrypted)
{
using (Stream cryptoStream = new CryptoStream(stream, m_Encryptor, CryptoStreamMode.Write))
{
// 3. write to the cryptoStream
m_Formatter.Serialize(cryptoStream, pObject);
}
}
else
m_Formatter.Serialize(stream, pObject);
}
}
int AccNum;
FileStream myfile = new FileStream("C:\\bankin.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamReader rd = new StreamReader(myfile);
StreamWriter wt = new StreamWriter(myfile);
int a = Convert.ToInt32(rd.ReadLine());
AccNum = a;
a += 1;
wt.WriteLine(Convert.ToString(a));
Console.WriteLine(rd.ReadLine());
rd.Close();
wt.Close();
myfile.Close();
I am trying to increment an integer value in the file banking.txt, but I am getting the following error:
Cannot access a closed file
Perhaps it's because you're closing rd before wt?
If that is the case, I would recommend using the using statement to prevent this confusion in the future:
int AccNum;
using (FileStream myfile = new FileStream("C:\\bankin.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) {
using (StreamReader rd = new StreamReader(myfile)) {
using (StreamWriter wt = new StreamWriter(myfile)) {
int a = Convert.ToInt32(rd.ReadLine());
AccNum = a;
a += 1;
wt.WriteLine(Convert.ToString(a));
Console.WriteLine(rd.ReadLine());
}
}
}
Change your code to make use of the using statements
Provides a convenient syntax that ensures the correct use of
IDisposable objects.
int AccNum;
using(FileStream myfile = new FileStream("C:\\bankin.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
using(StreamReader rd = new StreamReader(myfile))
using (StreamWriter wt = new StreamWriter(myfile))
{
int a = Convert.ToInt32(rd.ReadLine());
AccNum = a;
a += 1;
wt.WriteLine(Convert.ToString(a));
Console.WriteLine(rd.ReadLine());
}
int AccNum;
using(FileStream myfile = new FileStream("C:\\bankin.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using(StreamReader rd = new StreamReader(myfile))
{
using(StreamWriter wt = new StreamWriter(myfile))
{
int a = Convert.ToInt32(rd.ReadLine());
AccNum = a;
a += 1;
wt.WriteLine(Convert.ToString(a));
}
Console.WriteLine(rd.ReadLine());
}
}
It's good practice to use 'using'.
the exception is produced by the line wt.Close() because the file is already closed. the Close method on StreamReader close stream and all the underlying resources (see http://msdn.microsoft.com/en-us/library/system.io.streamreader.close.aspx)
and I assume that you want to save changes, so use Flush to save or use Close with AutoFlush in place of Flush. here is your example with some modification
int AccNum;
using (FileStream myfile = new FileStream("test.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (StreamReader rd = new StreamReader(myfile))
{
using (StreamWriter wt = new StreamWriter(myfile))
{
int a = Convert.ToInt32(rd.ReadLine());
AccNum = a;
a += 1;
wt.WriteLine(Convert.ToString(a));
Console.WriteLine(rd.ReadLine());
wt.Flush();
}
}
}
My problem is that I can not open the file. In another process or in the same process!
Code:
var path = #"c:\work\mmf.dat";
var map = "testmap123";
var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
if (fs.Length == 0)
{
fs.SetLength(1024);
}
var sec = new MemoryMappedFileSecurity();
var mem = MemoryMappedFile.CreateFromFile(fs, map, fs.Length, MemoryMappedFileAccess.ReadWrite, sec, HandleInheritability.Inheritable, false);
// Problem here System.UnauthorizedAccessException
var tmp = MemoryMappedFile.OpenExisting(map, MemoryMappedFileRights.FullControl, HandleInheritability.Inheritable);
Try the following:
var path = #"c:\diverse\mmf.dat";
var map = "testmap123";
using (var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
if (fs.Length == 0)
{
fs.SetLength(1024);
}
}
using (var mem = MemoryMappedFile.CreateFromFile(path, FileMode.Open, map, 1024, MemoryMappedFileAccess.Read))
{
using (var tmp = MemoryMappedFile.OpenExisting(map))
{
//work with tmp
}
}
The following code sample shows how to serialize/deserialize to a file. How could I modify this to serialize to a variable instead of to a file? (Assume the variable would be passed in to the read/write methods instead of a file name).
public static void WriteObject(string fileName)
{
Console.WriteLine(
"Creating a Person object and serializing it.");
Person p1 = new Person("Zighetti", "Barbara", 101);
FileStream writer = new FileStream(fileName, FileMode.Create);
DataContractSerializer ser =
new DataContractSerializer(typeof(Person));
ser.WriteObject(writer, p1);
writer.Close();
}
public static void ReadObject(string fileName)
{
Console.WriteLine("Deserializing an instance of the object.");
FileStream fs = new FileStream(fileName,
FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(Person));
// Deserialize the data and read it from the instance.
Person deserializedPerson =
(Person)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
Console.WriteLine(String.Format("{0} {1}, ID: {2}",
deserializedPerson.FirstName, deserializedPerson.LastName,
deserializedPerson.ID));
}
You can change the FileStream to a memory stream and dump it to a byte[].
public static byte[] WriteObject<T>(T thingToSave)
{
Console.WriteLine("Serializing an instance of the object.");
byte[] bytes;
using(var stream = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(stream, thingToSave);
bytes = new byte[stream.Length];
stream.Position = 0;
stream.Read(bytes, 0, (int)stream.Length);
}
return bytes;
}
public static T ReadObject<T>(byte[] data)
{
Console.WriteLine("Deserializing an instance of the object.");
T deserializedThing = default(T);
using(var stream = new MemoryStream(data))
using(var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()))
{
var serializer = new DataContractSerializer(typeof(T));
// Deserialize the data and read it from the instance.
deserializedThing = (T)serializer.ReadObject(reader, true);
}
return deserializedThing;
}